sheet - neo4j tutorial
Crear asociaciĆ³n entre nodos si uno no existe usando cypher (4)
Supongamos que hay 2 etiquetas P y M. M tiene nodos con los nombres M1, M2, M3..M10. Necesito asociar 50 nodos de P con cada Nodo de M. Además, ningún nodo de la etiqueta P debería tener 2 asociaciones con el nodo de M.
Esta es la consulta de cifrado que podría surgir, pero parece que no funciona.
MATCH (u:P), (r:M{Name:''M1''}),(s:M)
where not (s)-[:OWNS]->(u)
with u limit 50
CREATE (r)-[:OWNS]->(u);
De esta manera correría para los 10 nodos de M. Se agradece cualquier ayuda para corregir la consulta.
Creo que una forma de conectar los 10 nodos: M en una consulta
MATCH (m:M)
WITH collect(m) as nodes
UNWIND nodes as node
MATCH (p:P) where not ()-[:OWNS]->(p)
WITH node,p limit 50
CREATE (node)-[:OWNS]->(p)
Aunque no estoy muy seguro de si tenemos que recopilar y relajar, simplemente podríamos simplificarlo para:
MATCH (m:M)
MATCH (p:P) where not ()-[:OWNS]->(p)
WITH m,p limit 50
CREATE (node)-[:OWNS]->(p)
Esta consulta debe ser rápida y fácil de entender. Es rápido porque evita productos cartesianos :
MATCH (u:P)
WHERE not (:M)-[:OWNS]->(u)
WITH u LIMIT 50
MATCH (r:M {Name:''M1''})
CREATE (r)-[:OWNS]->(u);
Primero coincide con 50 nodos P
no propietarios. Luego encuentra el nodo M
que se supone que es el "propietario" y crea una relación OWNS
entre él y cada uno de los 50 nodos P
Para que esta consulta sea aún más rápida, primero puede crear un índice en :M(Name)
para que el nodo M
propietario se pueda encontrar rápidamente (sin escanear todos los nodos M
):
CREATE INDEX ON :M(Name);
Esto funcionó para mí.
MATCH (u:P), (r:M{Name:''M1''}),(s:M)
where not (s)-[:OWNS]->(u)
with u,r limit 50
CREATE (r)-[:OWNS]->(u);
Gracias por Thomas por mencionar el límite en u y r.
Puede utilizar la biblioteca apoc.periodic. * Para lotes. Más información en documentación
call apoc.periodic.commit("
MATCH (u:P), (r:M{Name:''M1''}),(s:M) where not (s)-[:OWNS]->(u)
with u,r limit {limit}
CREATE (r)-[:OWNS]->(u)
RETURN count(*)
",{limit:10000})
Si siempre habrá una sola relación (r)-[:OWNS]->(u)
, cambiaría mi primera coincidencia para incluir
call apoc.periodic.commit("
MATCH (u:P), (r:M{Name:''M1''}),(s:M) where not (s)-[:OWNS]->(u) and not (r)-[:OWNS]->(u)
with u,r limit {limit}
CREATE (r)-[:OWNS]->(u)
RETURN count(*)
",{limit:10000})
Entonces, no hay forma de que el procedimiento caiga en un bucle