Neo4J/Gremlin/Cypher: ¿Cómo obtener todos los nodos hasta que alcance una cierta distancia (profundidad) en una configuración similar a un mapa?
Pregunta
Tengo un gráfico simple con campos: cada campos tiene 4 vecinos (noreste-sur-oeste):
@NodeEntity
public class Field {
@GraphId
Long id;
Field north;
Field east;
Field south;
Field west;
//.. other stuff
}
I Un gráfico DB (Neo4J) configurado, por lo que todos son agradables y conectados (como una cuadrícula). Lo que quiero hacer ahora es obtener todos los nodos, de un nodo inicial, que están a 5 saltos de distancia.
Con un recorrido clásico, esto funciona bien y se ve así:
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;
}
Entonces, si tengo un "mapa" como este:
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
Y consulto con el nodo inicial '' 13 '' y una "profundidad" de 2 necesito obtener los 12 nodos marcados, ya que están a 2 pasos de 13.
Usé Jo4Neo en este ...
¿Cómo puedo lograr la misma funcionalidad en Cypher o Gremlin?
Encontré el ejemplo de amigo de amigo, pero esto realmente no me ayuda, porque necesito la profundidad para ser un parámetro (es decir, en algunos casos quiero una profundidad de 4, a veces 6).
Nota: También hay otras conexiones excepto los campos, pero obviamente solo necesito los campos. También necesito obtener todos los nodos conectados, no solo en una dirección.
Solución: Gracias al puntero obtuve la solución:
start n=node(13) match n-[*1..2]->b where b.__type__ = "model.Field" return distinct b
Solución
http://docs.neo4j.org/chunked/snapshot/query-match.html#match-variable-lengthing-relationships
START a=node(3)
MATCH a-[:FRIEND*1..3]->x
RETURN a,x
Si quieres exactamente 3 pasos:
MATCH a-[:FRIEND*3..3]->x
¡Espero que esto ayude!
Otros consejos
¿Y qué hacer para encontrar un nivel de profundidad? medios como *1..3
Muestra "a-> b, a-> b-> c & a-> b-> c-> d" como resultado de la consulta de Cypher de Andres, ¿qué es lo que quiero encontrar un recuento de profundidad, es decir, 1 en caso de a-> b; 2 en caso de a-> b-> c y así.