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

前回までで、ひとまず作ったデータがNeo4jの中に入ってきた。ここからいろいろデータをいじる訳だが、慣れる意味も含めていろいろのパターンで動かしてみることにする。

py2neoから直接cypherクエリを発行してみる

前回、py2neoの機能に頼りすぎて少し失敗したので、py2neoに直接cypherクエリを受け渡すという方法を試す。cypher.execute()を使うと括弧の中にCypherのクエリをそのまま受け渡して実行することが出来る。

w = graph.cypher.execute("MATCH (w:Word) WHERE w.keyword='熬夜' RETURN w") 
print(w)

気をつけないと行けないのは、キーワード大文字のルールを遵守しないと怒られる点だ。Neo4jの中から直接実行するときは、MATCHなどのキーワードを小文字で入れても大目に見てくれるのだが、ここではダメらしい。一応、pythonから呼んでいるのでwという変数に値を返すようにしている。戻りはこんな感じ。

   | w                                                                       
---+--------------------------------------------------------------------------
 1 | (n2:Word {keyword:"熬夜",meaning:"徹夜する",pinyin:"ao2 ye4",pinyinf:"áo yè"})

無事に前回登録したデータの1つが出てきた。この出てきたデータをどう扱えば良いのか?その前にこの戻り値は何者かを確認。

type(w)
py2neo.cypher.core.RecordList

見れば分かるけど独自の型なのね。RecordListの先頭レコードだけ欲しいときは、oneを使えばNodeとして返してくれる。

print(type(w.one),w.one['keyword'])
<class 'py2neo.core.Node'> 熬夜

Nodeとして返してくれるということは、ディクショナリと同じ形式で属性を指定してやれば、必要な値が拾える。RecordListはリストなので、あらかじめ入っているエントリの順番が分かっているなら、直接取り出しても良い訳だ。

type(w[0])
py2neo.cypher.core.Record

触った感じ、速さ的にもストレスは感じない。

find()と何が違う?

レコードを取得するぐらいなら、cypher.execute()を呼び出すまでもなく、find()でも行ける。キーが1つしか使えないという点は問題だが。こちらも試してみる。レコード取得後の取り扱いを理解する意味で、型も一緒に出力する。

w = list(graph.find("Word", "keyword", "熬夜"))
print(type(w), type(w[0]), w)
<class 'list'> <class 'py2neo.core.Node'> [<Node graph='http://localhost:7474/db/data/' ref='node/571' labels={'Word'} properties={'pinyin': 'ao2 ye4', 'keyword': '熬夜', 'meaning': '徹夜する', 'pinyinf': 'áo yè'}>]

find()を使った場合の戻り値はリスト(list)の中にNodeが入っている事が分かる。という事は、ディクショナリと同じ形式で指定すれば値を取り出せる。

w[0]["keyword"]
'熬夜'

こちらの検索も1回目は遅く感じたが、2回目からはストレスを感じなくなった。DB側でバッファするというのは一般のRDBMSと同じような機能を備えているんだろう。

かなり駆け足だったけど、次回はRelationshipを使った検索を見てみる。

(つづく)

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

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