← Blog

Jun 13, 2026 · Updated Jul 11, 2026

Learning Neo4j: A Japanese Citrus Family Tree

Using Japanese citrus varieties to learn graph modeling with parent-child relationships, intermediate breeding lines, and path queries.

Learning Neo4j: A Japanese Citrus Family Tree

Graph modeling becomes easier when we can see relationships in familiar data.

This article uses mikan and other Japanese citrus varieties as a small graph modeling example. The source idea is based on a citrus family tree displayed at Orange BAR in Matsuyama Airport.

A citrus family tree is a good graph example. Each variety can have parent varieties. Some varieties become parents of other varieties. Some paths are short, and some paths continue through multiple generations.

The goal is not only to learn Cypher commands.

The goal is to see how lineage, ancestry, and derivation can be represented as a graph.

Japanese note:
この記事では、みかん・柑橘の品種家系図を題材にして、Neo4j の基本とグラフモデリングを学びます。目的はコマンドを試すことだけではなく、品種の親子関係やルーツをグラフとして表現することです。

Why Japanese citrus?

Many graph examples use social networks, product recommendations, or IT systems. These are useful, but a family tree is often easier to understand.

A citrus variety can have parent varieties. A variety can become the parent of another variety. A variety can have many descendants. A variety can also have ancestors several generations back.

These relationships are naturally graph-shaped.

The same pattern appears in many other domains:

  • product genealogy
  • data lineage
  • document versions
  • component dependencies
  • biological taxonomy
  • system inheritance
  • knowledge provenance

A citrus family tree is a small and friendly way to learn these ideas.

Starting from a citrus family tree

The original workshop was based on an Ehime citrus family tree displayed at Orange BAR in Matsuyama Airport.

Mikan family tree

Data model

In this article, each citrus variety becomes a Mikan node.

Parent-child relationships are represented with PARENT_OF.

(parent)-[:PARENT_OF]->(child)

The direction is from parent to child. This makes the graph easy to read as a family tree.

The original workshop used CHILD as the relationship name. In this blog version, I use PARENT_OF because the direction is easier to understand.

The source family tree also includes several labels named 中間母本.

In this article, they are not modeled as one shared node. They are separated into three intermediate breeding lines:

  • 中間母本(はれひめ系) — Intermediate Parent for Harehime
  • 中間母本(せとか系) — Intermediate Parent for Setoka
  • 中間母本(天草系) — Intermediate Parent for Amakusa

This is an important graph modeling point:

A label in the source data is not always a unique entity.

Japanese note:
中間母本 は、特定の一つの品種名というより、中間的な親系統を表している場合があります。このような場合、同じ名前でも同じ実体とは限りません。この記事では、用途が分かるように 中間母本(はれひめ系)中間母本(せとか系)中間母本(天草系) に分けて扱います。

Loading mikan data

The first step is to load citrus variety names from a CSV file.

The full CSV is available as a download. In this article, I show only a few rows so that the main focus stays on graph modeling rather than raw data.

Sample CSV for this article mikan.csv — citrus variety data used in the examples
Download CSV

After downloading the CSV, place it under the Neo4j import directory as csv/mikan.csv.

Japanese note:
サンプルCSV全体はダウンロードできます。ダウンロードしたCSVは、Neo4j の import ディレクトリ配下に csv/mikan.csv として配置します。

A small part of the CSV looks like this:

"name","kana","english","alias","alias_kana","alias_english"
"宮川早生","みやがわわせ","Miyagawa Wase","","",""
"トロビタ","とろびた","Trovita","","",""
"温州","うんしゅう","Unshu","","",""
"キング","きんぐ","King","","",""
"カラ","から","Kara","","",""
"中間母本(はれひめ系)","ちゅうかんぼほんはれひめけい","Intermediate Parent for Harehime","中間母本","ちゅうかんぼほん","Intermediate Parent"
"あいか28号","あいかにじゅうはちごう","Aika No. 28","紅まどんな","べにまどんな","Beni Madonna"

Before loading the data, create a uniqueness constraint for Mikan.name.

CREATE CONSTRAINT mikan_name_unique IF NOT EXISTS
FOR (n:Mikan)
REQUIRE n.name IS UNIQUE;

Then load the CSV.

LOAD CSV WITH HEADERS FROM 'file:///csv/mikan.csv' AS row
CREATE (n:Mikan {
  name: trim(row.name),
  kana: trim(row.kana),
  english: trim(row.english),
  alias: trim(row.alias),
  aliasKana: trim(row.alias_kana),
  aliasEnglish: trim(row.alias_english)
});

The dataset includes variety names such as:

  • 宮川早生 (Miyagawa Wase)
  • トロビタ (Trovita)
  • 清見 (Kiyomi)
  • はれひめ (Harehime)
  • ポンカン (Ponkan)
  • 不知火 (Shiranuhi)
  • 甘平 (Kanpei)
  • あいか28号 (Aika No. 28, alias: 紅まどんな / Beni Madonna)
  • 興津早生 (Okitsu Wase)

These are Japanese names, so the query examples also use Japanese text. Neo4j can store and search Japanese strings as normal text.

Searching Japanese text

Once the nodes are loaded, we can search by name.

For example, to find varieties whose names include 早生:

MATCH (n:Mikan)
WHERE n.name CONTAINS '早生'
RETURN n;

We can also search by kana.

MATCH (n:Mikan)
WHERE n.kana CONTAINS 'わせ'
RETURN n;

This is a simple query, but it is useful. It shows that we can start with text data first, then add relationships later.

Japanese note:
まずは名前やかなで検索します。最初から完璧なグラフモデルを作る必要はありません。既存のテキストデータを読み込み、少しずつ関係を追加していきます。

Creating the first parent-child relationship

Let’s start with a small example.

In this simplified model, 宮川早生 and トロビタ are parent varieties of 清見.

MATCH (n1:Mikan {name: '宮川早生'})
MATCH (n2:Mikan {name: 'トロビタ'})
MATCH (n3:Mikan {name: '清見'})
MERGE (n1)-[:PARENT_OF]->(n3)
MERGE (n2)-[:PARENT_OF]->(n3);

Now we can see the first parent-child relationship.

MATCH p=()-[:PARENT_OF]->()
RETURN p;

First parent-child relationship

This is the basic pattern of the article.

A parent variety points to a child variety.

(parent)-[:PARENT_OF]->(child)

Building the citrus family tree

Next, we add the remaining parent-child relationships.

The original workshop generated many MATCH statements using a spreadsheet. This is a practical approach when the number of varieties is small and the data is prepared manually.

Creating MATCH statements

The following example adds the main relationships.

MATCH (n1:Mikan {name: '宮川早生'})
MATCH (n2:Mikan {name: 'トロビタ'})
MATCH (n3:Mikan {name: '温州'})
MATCH (n4:Mikan {name: 'キング'})
MATCH (n5:Mikan {name: 'カラ'})
MATCH (n6:Mikan {name: 'アンコール'})
MATCH (n7:Mikan {name: 'マーコット'})
MATCH (n8:Mikan {name: 'せとか'})
MATCH (n9:Mikan {name: '日向夏'})
MATCH (n10:Mikan {name: 'はるか'})
MATCH (n11:Mikan {name: '黄金柑'})
MATCH (n12:Mikan {name: '媛小春'})
MATCH (n13:Mikan {name: '清見'})
MATCH (n14:Mikan {name: 'オセオラ'})
MATCH (n15h:Mikan {name: '中間母本(はれひめ系)'})
MATCH (n15s:Mikan {name: '中間母本(せとか系)'})
MATCH (n15a:Mikan {name: '中間母本(天草系)'})
MATCH (n16:Mikan {name: 'はれひめ'})
MATCH (n17:Mikan {name: 'ポンカン'})
MATCH (n18:Mikan {name: '不知火'})
MATCH (n19:Mikan {name: 'はるみ'})
MATCH (n20:Mikan {name: '西之香'})
MATCH (n21:Mikan {name: '甘平'})
MATCH (n22:Mikan {name: 'ページ'})
MATCH (n23:Mikan {name: '天草'})
MATCH (n24:Mikan {name: '南香'})
MATCH (n25:Mikan {name: 'あいか28号'})
MATCH (n26:Mikan {name: '興津早生'})

// 清見 (Kiyomi)
MERGE (n1)-[:PARENT_OF]->(n13)
MERGE (n2)-[:PARENT_OF]->(n13)

// カラ (Kara)
MERGE (n3)-[:PARENT_OF]->(n5)
MERGE (n4)-[:PARENT_OF]->(n5)

// 媛小春 (Hime Koharu)
MERGE (n11)-[:PARENT_OF]->(n12)
MERGE (n13)-[:PARENT_OF]->(n12)

// 中間母本(はれひめ系) (Intermediate Parent for Harehime)
MERGE (n13)-[:PARENT_OF]->(n15h)
MERGE (n14)-[:PARENT_OF]->(n15h)

// はれひめ (Harehime)
MERGE (n1)-[:PARENT_OF]->(n16)
MERGE (n15h)-[:PARENT_OF]->(n16)

// 中間母本(せとか系) (Intermediate Parent for Setoka)
MERGE (n13)-[:PARENT_OF]->(n15s)
MERGE (n6)-[:PARENT_OF]->(n15s)

// せとか (Setoka)
MERGE (n15s)-[:PARENT_OF]->(n8)
MERGE (n7)-[:PARENT_OF]->(n8)

// 不知火 (Shiranuhi)
MERGE (n13)-[:PARENT_OF]->(n18)
MERGE (n17)-[:PARENT_OF]->(n18)

// はるみ (Harumi)
MERGE (n13)-[:PARENT_OF]->(n19)
MERGE (n17)-[:PARENT_OF]->(n19)

// 甘平 (Kanpei)
MERGE (n17)-[:PARENT_OF]->(n21)
MERGE (n20)-[:PARENT_OF]->(n21)

// はるか (Haruka)
MERGE (n9)-[:PARENT_OF]->(n10)

// 中間母本(天草系) (Intermediate Parent for Amakusa)
MERGE (n13)-[:PARENT_OF]->(n15a)
MERGE (n26)-[:PARENT_OF]->(n15a)

// 天草 (Amakusa)
MERGE (n15a)-[:PARENT_OF]->(n23)
MERGE (n22)-[:PARENT_OF]->(n23)

// あいか28号(紅まどんな) (Aika No. 28 / Beni Madonna)
MERGE (n23)-[:PARENT_OF]->(n25)
MERGE (n24)-[:PARENT_OF]->(n25);

We can now show the registered citrus family tree.

MATCH p=(:Mikan)-[:PARENT_OF]->(:Mikan)
RETURN p;

Mikan full graph

Querying a variety

Now we can ask questions about a specific variety.

For example, find 清見.

MATCH (n:Mikan {name: '清見'})
RETURN n;

Kiyomi node

Finding direct children

Which varieties were created from 清見?

MATCH p=(:Mikan {name: '清見'})-[:PARENT_OF]->(:Mikan)
RETURN p;

Direct children of Kiyomi

This query follows one PARENT_OF relationship from 清見 to its direct children.

Finding descendants

We can also follow the family tree for multiple generations.

Which varieties have 清見 as one of their roots?

MATCH p=(:Mikan {name: '清見'})-[:PARENT_OF]->{1,10}(:Mikan)
RETURN p;

Descendants of Kiyomi

This is where graph databases become useful.

A relational database can store parent-child rows, but graph queries make it natural to follow paths across multiple generations.

Finding parents

We can also query in the opposite direction.

For example, what are the parents of はれひめ?

MATCH p=(:Mikan {name: 'はれひめ'})<-[:PARENT_OF]-(:Mikan)
RETURN p;

Parents of Harehime

We can also follow ancestors until there are no more parents.

MATCH p=(:Mikan {name: 'はれひめ'})<-[:PARENT_OF]-{1,10}(m:Mikan)
WHERE NOT (m)<-[:PARENT_OF]-(:Mikan)
RETURN p;

Roots of Harehime

This query is asking:

Which paths go from はれひめ back to the oldest known ancestor varieties?

Japanese note:
はれひめ から親方向へたどることで、祖先にあたる品種を調べることができます。グラフでは、このような「ルーツをたどる」検索が自然に書けます。

Why this matters

This workshop is small, but it shows several important graph modeling ideas.

A variety can be connected to its parent varieties.

A variety can have descendants.

A name in the source data may not always mean one unique entity.

A family tree can be queried as paths.

These patterns are useful far beyond citrus data.

They appear in:

  • product genealogy
  • data lineage
  • system dependencies
  • document histories
  • software version relationships
  • component inheritance
  • knowledge graph construction

Graph databases are not only useful for large networks. They are also useful when ordinary data has important relationships.

A citrus family tree is a small example, but it shows the same modeling thinking that appears in real business and technical systems.

Need this in your project?

Graph modeling can start from a small review.

I support data modeling, GraphRAG architecture, migration planning, and internal workshops. 日本語・英語どちらでもご相談いただけます。

Discuss your case