Forma eficiente de encontrar el conjunto de nodos que tiene relaciones con nodos dados usando Neo4J
Pregunta
¿Existe una manera eficiente con dos nodos dados para encontrar un conjunto de sus nodos comunes (con relaciones definidas)?
Por ejemplo, tener nodos A1
, B1
, C1
-C4
conectado con las relaciones x
y y
:
A1 --x--> C1
A1 --x--> C2
A1 --x--> C3
B1 --y--> C2
B1 --y--> C3
B1 --y--> C4
un nodo común establecido para A1(x)
y B1(y)
sería [C2, C3]
.
Solución
En muchos casos, la estructura del dominio se puede aprovechar para mejorar el rendimiento. Digamos que sabes que en general tu A
Las entidades tienen menos x
relaciones en comparación con el número de y
relaciones en el B
entidades. Luego podría atravesar dos pasos del nodo A y ver dónde B
aparece el nodo y filtre el C
nodos de esta manera. Aquí hay algún código para este enfoque:
Set<Node> found = new HashSet<Node>();
for ( Relationship firstRel : a1.getRelationships( Reltypes.x, Direction.OUTGOING ) )
{
Node cNode = firstRel.getEndNode();
for ( Relationship secondRel : cNode.getRelationships( Reltypes.y, Direction.INCOMING ) )
{
Node bNode = secondRel.getStartNode();
if ( bNode.equals( b1 ) )
{
found.add( cNode );
break;
}
}
}
Otra forma sería iniciar dos hilos que escanean las relaciones desde cada lado.
Un tercer enfoque sería crear un índice especializado que ayudara a responder este tipo de consultas, lo que obviamente dañaría el rendimiento del inserto.
Otros consejos
En Gremlin (http://gremlin.tinkerpop.com), esto se expresa como tal:
setA._().out('x').in('y').retain(setB).back(2)
Esto es lo que hace cada paso:
- Comience en Seta (A1, A2, A3 en su ejemplo).
- Inicie una tubería de Gremlin.
- Tome los bordes etiquetados de "X" salientes de esos vértices SETA a C1, C2 y C3.
- Tome los bordes etiquetados "Y" entrantes de C1, C2 y C3.
- Filtre todos los pasos que no están en SETB (por lo tanto, solo existen rutas C2 y C3).
- Regrese a lo que vio hace 2 pasos, por lo tanto, C2 y C3.
¡Tada!
Buena suerte, Marko.