中国語学習×グラフデータベース(8) - Relationshipの検索

検索という意味では前回とほとんど同じ。

Cypher独特の書式

独特と言っても、決して取っつきにくいわけではない。py2neoからはmatch()を使う方法もあるが、前回からの流れで、cypher.execute()で実行している。

wl = graph.cypher.execute("MATCH (w:Word)-[r:is_categorized_as]->(c:Category) WHERE c.category='成語' RETURN w")

成語というカテゴリを持つ単語を引っ張ってくるという意味になるが、RETURN wと単語だけ返すように指定しているので、戻り値のリストはWordのNodeだけを返す。例えば、RETURN w, rとなればRelationshipも返すことにになるが、is_categorized_asというRelationshipが何か属性を持っている訳ではないので、あまり意味がない。

戻り値はRecordのListになっているので、中身だけ書き出すなら、こんな感じでOK。

for w in wl:
    print(type(w), w)
<class 'py2neo.cypher.core.Record'>  w                                                                                                      
---------------------------------------------------------------------------------------------------------
 (n5558:Word {keyword:"总而言之",meaning:"要するに、つまり",pinyin:"zong3 er2 yan2 zhi1",pinyinf:"zǒng ér yán zhī"})

<class 'py2neo.cypher.core.Record'>  w                                                                                                          
-------------------------------------------------------------------------------------------------------------
 (n5544:Word {keyword:"自力更生",meaning:"人に頼らず自力で行う",pinyin:"zi4 li4 geng4 sheng1",pinyinf:"zì lì gèng shēng"})

<class 'py2neo.cypher.core.Record'>  w                                                                                                            
---------------------------------------------------------------------------------------------------------------
 (n5433:Word {keyword:"众所周知",meaning:"広く知られている",pinyin:"zhong4 suo3 zhou1 zhi1",pinyinf:"zhòng suǒ zhōu zhī"})
...

戻って来た内容のサイズを調べるという意味では、RETURN count(w)とかでもいいのだが、to_subgraph()を使うのも悪くないと思う。orderはNodeの数を返す。

wl.to_subgraph().order
217

orderだけでなくrelationshipの数も知りたければsizeの値を拾えば良い。

wl.to_subgraph()
<Subgraph order=217 size=0>

慣れるには練習しかない

こういう事を書くと元も子もないんだけど、せっかくグラフデータベースに取り込んだデータを自由に取り出したり加工するには、やはりCypherの書式に慣れておくのが大事。これは最初の例だけど、いくつか決まり事を挙げておこう。

MATCH (w:Word)-[r:is_categorized_as]->(c:Category) WHERE c.category='成語' RETURN w
  1. Nodeは()で表現する。(変数名:ラベル名 {属性名:属性値})というのが基本パターン。属性値が単一値に絞り込めるなら{}を使って絞り込む。何かしらの条件を絞り込みたいなら、WHERE句の中で書けば良い。RETURNで戻さないなら変数名はいらないが、:は必要。
  2. Relationshipは[]で表現する。[変数名:ラベル名]というのが基本パターン。変数の省略については、Nodeと同じ決まりだと思えばOK。あとどんな関係性でも問わず、なおかつRETURNで拾う必要がないなら中身ブランクでもOK。(Nodeも同じ)
  3. Neo4jのRelationshipは有方向性なので、方向を意識した指定をする必要あり(例:-->, <--)。ただしノード間に両方向のRelationshipがあるなら-[]-という指定をするのもあり。
  4. RETURN句は必須だが、後続処理に必要なものだけを抽出すれば良い。例えば、keywordという属性値だけ欲しければ、RETURN w.keywordというような指定するのもあり。

等々

慣れるまでは、Neo4j側でクエリを試しながら実行して、結果が得られるのが確認できたら、Python側でコーディングするのが良いと思う。

次回は、もう少し凝った検索方法を採り上げる予定。

(つづく)

グラフ型データベース入門 - Neo4jを使う

グラフ型データベース入門 - Neo4jを使う

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門