Rails
neo4j

Neo4jrbでRelをfindする

More than 1 year has passed since last update.

Neo4jrbとは

 グラフィカルデータベースの一つであるNeo4jとruby/railsとの間のO/Gマッパー。要はrubyやrailsとneo4jデータベースを繋ぐパーツである。ActiveRecordはruby/railsとリレーショナルデータベースを繋いでいたが、それのグラフィカルデータベース版。

Neo4jrbの使い方

http://neo4jrb.readthedocs.io/en/9.0.x/ 

ActiveRecordとほぼ同じ。ただし、ActiveNodeとActiveRelという二つに分かれている。
ActiveNodeはノードオブジェクトのために存在する。ActiveRecordと同じようにfindメソッドなどが使える。
 ActiveRelはリレーションオブジェクトのために存在する。

Relを検索するには

 ActiveNodeはfindメソッドが使えるので、Nodeの検索は簡単にできる。一方で、Relにはfindメソッドがなく、あるノード同士の間にあるRelを検索するには、ノードから検索しなければいけない。

例えば、あるノードAとノードBの間にrelが存在するかどうかを調べるのは、
1. ノードAから出ている全てのRelを調べる
2. それらのRelの一つが、ノードBに繋がっているか調べる
のが必要。
例えば、
 A.each_rel{ |r| r.to_node == B ? break : return false }
のように書く。
Neo4jの生クエリであれば、
match (A)-[r]-(B) return r
でrが存在するなら、rが帰ってくるし、rが存在しなければnilになるから、わかりやすい。

要は、ここで多少面倒な処理をしなければならないのは、ActiveRelで、同時に二つのノードを指定できないことにある。特定のRelを検索するには、当然二つのノードが決まっていなければならないので、ふたつのノードを同時に指定できるメソッドが欲しい。

ちなみに、上の式は、
 A.query_as(:a).match('(a)-[r]-(b)').pluck(r)
みたいに生のクエリにAを組み入れることもできる。このquery_asメソッドが複数選択で使えると便利なのだが。

 (A,B).query_as(:a,:b).match('(a)-[r]-(b)').pluck(r)

みたいに。