Neo4j/Gremlin/Cypher: how to get all nodes until i reach a certain distance (depth) in a map-like setup?
문제
I have a simple graph with fields - each fields has 4 neighbours (north-east-south-west):
@NodeEntity
public class Field {
@GraphId
Long id;
Field north;
Field east;
Field south;
Field west;
//.. other stuff
}
I a graph db (neo4j) set up so these are all nice and connected (like a grid). What I want to do now is get all nodes - from a starting node - which are i.e. 5 hops away.
With a classic traverses this works fine and looks like this:
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;
}
So if I have a "map" like this:
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
and I query with starting node ''13'' and a "depth" of 2 I need to get the marked 12 nodes - since they are 2 steps aways from 13.
I used jo4neo in this...
How can I achieve the same functionality in cypher or gremlin?
I found the friend-of-friend example, but this does not really help me, because I need the depth to be a parameter (i.e. in some cases I want a depth of 4, sometimes 6).
Note: there are also other connections except Fields, but I obviously just need the fields. Also I need to get all connected nodes - not just in one direction.
Solution: Thanks to the pointer I got the solution:
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#match-variable-length-relationships
START a=node(3)
MATCH a-[:FRIEND*1..3]->x
RETURN a,x
If you want exactly 3 steps:
MATCH a-[:FRIEND*3..3]->x
Hope this helps!
다른 팁
And what to do to Find level of Depth? means as *1..3
displays "A->B, A->B->C & A->B->C->D" as a result of cypher query by Andres, what is I want to find a Count of depth, i.e., 1 in case of A->B; 2 in case of A->B->C & so on.