Neo4j/Gremlin/Cypher: how to get all nodes until i reach a certain distance (depth) in a map-like setup?

StackOverflow https://stackoverflow.com/questions/8804966

  •  26-10-2019
  •  | 
  •  

Question

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
Was it helpful?

Solution

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!

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top