リレーションの表現

ノード間の関連を表すにはRelationshipオブジェクトを用いる。図2のような簡単な関連を考えてみよう。

図2 リレーションの例

上手の関連を定義するコード例を以下に示す。Relationshipオブジェクトにはノードと同様に任意のプロパティを設定することができるため、関連を定義するだけでなく、付加的な情報を持たせることも可能だ。

// 関連のタイプを表現する列挙型
public enum MyRelationshipTypes implements RelationshipType {
  WORKS_AT
}

...

// 1つめのノードを作成
Node person = graphDb.createNode();
person.setProperty("name", "Naoki Takezoe");

// 2つめのノードを作成
Node company = graphDb.createNode();
company.setProperty("name", "NTT DATA INTELLILINK");

// 1つめのノードから2つめのノードへの関連を定義
Relationship relationship = person.createRelationshipTo(company, MyRelationshipTypes.WORKS_AT);
relationship.setProperty("message", "Hello neo4j!");

ノードの検索

続いてノードを検索する方法をみてみよう。neo4jでは以下のような検索手段が用意されている。

  1. すべてのノードをIteratorで取得
  2. IDを指定して特定のノードを取得
  3. Traverserを使用した検索

この中でも特に利用頻度が高く重要なのがTraverserを使用した検索だ。基点となるノードを取得し、Node#traverse()メソッドを呼び出すことで関連を持つノードをトラバースすることができる。トラバースを行うコードの例を以下に示す。

// 基点となるノードを取得
Node company = ...

// MyRelationshipTypes.EMPLOYSの関連をたどるトラバーサ
Traverser traverser = company.traverse(
  Order.DEPTH_FIRST,
  StopEvaluator.END_OF_GRAPH,
  ReturnableEvaluator.ALL_BUT_START_NODE,
  MyRelationshipTypes.EMPLOYS,
  Direction.OUTGOING);

for(Node employee: traverser){
  ...
}

上記の例ではMyRelationshipTypes.EMPLOYSの関連をたどっているが、ReturnableEvaluatorを拡張することでその他の条件を付加することができる。以下の例ではMyRelationshipTypes.EMPLOYSの関連をたどり、roleプロパティがEngineerのノードを返却するTraverserを取得している。

Traverser traverser = startNode.traverse(
  Order.DEPTH_FIRST,
  StopEvaluator.END_OF_GRAPH,
  new ReturnableEvaluator() {
    @Override
    public boolean isReturnableNode(TraversalPosition pos) {
      return pos.currentNode().getProperty("role").equals("Engineer");
    }
  },
  MyRelationshipTypes.EMPLOYS,
  Direction.OUTGOING);

このようにneo4jで検索を行うにはノード間のリレーションの設計とTraverserの使い方が重要なポイントになってくる。