Neo4J/Gremlin/Cypher:マップのようなセットアップで特定の距離(深さ)に達するまですべてのノードを取得する方法は?
質問
私はフィールドを持つ簡単なグラフを持っています - 各フィールドには4つの隣人(北東南西)があります:
@NodeEntity
public class Field {
@GraphId
Long id;
Field north;
Field east;
Field south;
Field west;
//.. other stuff
}
IグラフDB(NEO4J)が設定されているため、これらはすべて素晴らしく接続されています(グリッドのように)。私が今やりたいのは、すべてのノードを取得することです - 開始ノードから - IE 5ホップアウェイです。
古典的なトラバースでこれは正常に機能し、次のようになります:
public Collection<Field> getFieldsWithDepth(Field startField, final int depth) {
Node fieldNode = this.getGraphdb().getNodeById(startField.getId());
Traverser traverser = fieldNode.traverse(Traverser.Order.BREADTH_FIRST, // check direct relations first, then go deeper
new StopEvaluator() {
@Override
public boolean isStopNode(TraversalPosition pos) {
if (pos.depth()==depth)
return true;
else
return false;
}
}, // worst case: go to end of graph
new ReturnableEvaluator() {
@Override
public boolean isReturnableNode(TraversalPosition pos) {
return true;
}
},
Relations.north,
Direction.OUTGOING,
Relations.east,
Direction.OUTGOING,
Relations.west,
Direction.OUTGOING,
Relations.south,
Direction.OUTGOING
);
ArrayList<Field> fields = new ArrayList<Field>();
for (Node node : traverser.getAllNodes())
{
fields.add((Field)this.getGraph().get(node));
}
return fields;
}
したがって、私がこのような「マップ」を持っている場合:
1 2 | 3| 4 5
6 |7| | 8| | 9| 10
|11| |12| *13* |14| |15|
16 |17| |18| |19| 20
21 22 |23| 24 25
そして、開始ノード '' 13 ''と2の「深さ」でクエリをします。13から2つのステップがあるため、マークされた12ノードを取得する必要があります。
私はこれでJo4neoを使用しました...
CypherまたはGremlinで同じ機能を達成するにはどうすればよいですか?
友達の友達の例を見つけましたが、これは本当に私を助けません。なぜなら、深さをパラメーターにする必要があるからです(つまり、場合によっては4、時には6の深さが必要です)。
ノート: フィールド以外の他の接続もありますが、明らかにフィールドが必要です。また、一方向だけでなく、すべての接続ノードを取得する必要があります。
解決: ポインターのおかげで、私は解決策を得ました:
start n=node(13) match n-[*1..2]->b where b.__type__ = "model.Field" return distinct b
解決
http://docs.neo4j.org/chunked/snapshot/query-match.html#-variable-length-relationships
START a=node(3)
MATCH a-[:FRIEND*1..3]->x
RETURN a,x
正確に3つのステップが必要な場合:
MATCH a-[:FRIEND*3..3]->x
お役に立てれば!
他のヒント
そして、深さのレベルを見つけるために何をすべきか? ASを意味します *1..3
"a-> b、a-> b-> c&a-> b-> c-> d"を表示します。 a-> bの場合; 2 a-> b-> c&soの場合。