Neo4j Mikan Orange Workshop

November 16, 2024

みかん


Neo4jを学びましょう


参考になる録画はこちらです。 動画を見ながらここのコマンドをコピペして学びましょう。

データ登録


松山空港のOrange BARの店舗にあった「愛媛のかんきつ家系図」をベースにしました。

https://www.matsuyama-airport.co.jp/service/buy/orangebar.html

mikan-family-tree.png

csvを作成します。ツールは何でも構いません。

下記のデータをテキストに貼り付けてcsvで保存します。

mikan.csv

"name","kana"
"宮川早生","みやがわわせ"
"トロビタ","とろびた"
"温州","うんしゅう"
"キング","きんぐ"
"カラ","から"
"アンコール","あんこーる"
"マーコット","まーこっと"
"せとか","せとか"
"日向夏","ひゅうがなつ"
"はるか","はるか"
"黄金柑","おうごんかん"
"媛小春","ひめこはる"
"清見","きよみ"
"オセオラ","おせおら"
"中間母本","ちゅうかんぼほん"
"はれひめ","はれひめ"
"ポンカン","ぽんかん"
"不知火","しらぬい"
"はるみ","はるみ"
"西之香","にしのかおり"
"甘平","かんぺい"
"ページ","ペーじ"
"天草","あまくさ"
"南香","なんこう"
"紅まどんな","べにまどんな"
"興津早生","おきつわせ"

csvデータを配置します。

Neo4j Home/importに入れます。 今回は、csvと言うフォルダーを作ってmikan.csvを設置しました。

LOAD CSV WITH HEADERS FROM 'file:///csv/mikan.csv' AS line
INSERT (n:Mikan {
  name: trim(line.name),
  kana: trim(line.kana)
  });

検索


名前に「早生(わせ)」が含まれているもの

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

かなに「わせ(早生)」が含まれているもの

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

試しに家系図を作りましょう


宮川早生とトロビタから清見の品種ができました

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

リレーションを見てみましょう

MATCH p=()-[r:CHILD]->() RETURN p LIMIT 25

child-one.png

残りの家系図を作りましょう


全てのMATCH文を作りましょう

MATCH文は少ないのでLibreOfficeのCalcで加工して作りました。

="MATCH (n"&ROW(A2)-1&":Mikan {name: '"&A2&"'})"

create-match.png

親子の関係を追加します

中間母本以外の関係を追加します。

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 (n15: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: '紅まどんな'})
MATCH (n26:Mikan {name: '興津早生'})
// 清見
MERGE (n1)-[:CHILD]->(n3)
MERGE (n2)-[:CHILD]->(n3)
// 媛小春
MERGE (n11)-[:CHILD]->(n12)
MERGE (n13)-[:CHILD]->(n12)
// 中間母本
MERGE (n14)-[:CHILD]->(n15)
MERGE (n13)-[:CHILD]->(n15)
// はれひめ
MERGE (n1)-[:CHILD]->(n16)
MERGE (n15)-[:CHILD]->(n16)
// 不知火
MERGE (n13)-[:CHILD]->(n18)
MERGE (n17)-[:CHILD]->(n18)
// はるみ
MERGE (n13)-[:CHILD]->(n19)
MERGE (n17)-[:CHILD]->(n19)
// 甘平
MERGE (n17)-[:CHILD]->(n21)
MERGE (n20)-[:CHILD]->(n21)
// はるか
MERGE (n9)-[:CHILD]->(n10)
// 紅まどんな
MERGE (n23)-[:CHILD]->(n25)
MERGE (n24)-[:CHILD]->(n25)
// カラ
MERGE (n3)-[:CHILD]->(n5)
MERGE (n4)-[:CHILD]->(n5)

登録データ

MATCH (n) RETURN n

mikan-except-cyukan.png

中間母本は特定の品種の名前ではない事がわかったので追加

MATCH (n6:Mikan {name: 'アンコール'})
MATCH (n7:Mikan {name: 'マーコット'})
MATCH (n8:Mikan {name: 'せとか'})
MATCH (n13:Mikan {name: '清見'})
MATCH (n22:Mikan {name: 'ページ'})
MATCH (n23:Mikan {name: '天草'})
MATCH (n26:Mikan {name: '興津早生'})
// 中間母本
CREATE (add1:Mikan {name:'中間母本', kana:'ちゅうかんぼほん'})
CREATE (add2:Mikan {name:'中間母本', kana:'ちゅうかんぼほん'})
// 中間母本(追加)
MERGE (n13)-[:CHILD]->(add1)
MERGE (n6)-[:CHILD]->(add1)
// せとか
MERGE (add1)-[:CHILD]->(n8)
MERGE (n7)-[:CHILD]->(n8)
// 中間母本(追加)
MERGE (n13)-[:CHILD]->(add2)
MERGE (n26)-[:CHILD]->(add2)
// 天草
MERGE (add2)-[:CHILD]->(n23)
MERGE (n22)-[:CHILD]->(n23)

登録データ

MATCH (n) RETURN n

mikan-all.png

検索


清見

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

mikan-kiyomi.png

清見を使った交配種

リレーションを指定しなくても良い場合は省略できる

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

mikan-kiyomi-child.png

清見がルーツな交配種

リレーションを指定しなくても良い場合は省略できる

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

mikan-kiyomi-children.png

はれひめの先祖?

MATCH p=(:Mikan {name: 'はれひめ'})<--(m:Mikan)
RETURN p

mikan-harehime-parents.png

はれひめの先祖で先祖が無いところまでの経路

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

mikan-harehime-roots.png


Profile picture

Written by Koji Annoura who lives and works in Fukuoka Japan. You should follow them on Twitter