Neo4j: ¿cómo elimino todas las relaciones duplicadas en la base de datos a través de cifrado?

Tengo una gran base de datos con una tonelada de nodos (10mil +). Solo hay un tipo de relación en toda la base de datos. Sin embargo, hay una tonelada de nodos que tienen relaciones duplicadas entre ellos. Lo que tengo actualmente es este script encriptado que encuentra todos los pares con duplicados, y luego un script en Python que se ejecuta y limpia cada uno (dejando solo una relación única entre esos nodos).

match (a)-[r]->(b) with a,b, count(*) as c where c>1 return a.pageid, b.pageid, c LIMIT 100000;

esto funciona bastante bien para una pequeña base de datos, pero cuando lo ejecuto en una grande, eventualmente explota con una excepción acerca de quedarme sin memoria en el montón (subir la caja cada vez más no ayuda).

Entonces, la pregunta es doble: 1) ¿Existe algún tipo de indexación que pueda establecer en las relaciones (en este momento no hay ninguna) que ayude a acelerar esto? 2) ¿Existe una consulta encriptada que puede (de una manera rápida … o al menos de manera confiable) eliminar todas las relaciones duplicadas en la base de datos dejando solo una única para cada par de nodos (que ya tiene relación entre ellos)?

PS Estoy ejecutando neo4j 2.0.1 en una caja de AWS ubuntu (12something).

PPS Me doy cuenta de que existe esta respuesta: stackoverflow , sin embargo, lo que está preguntando es algo más específico (contra 2 nodos ya conocidos), y la respuesta que tiene la base de datos completa ya no se ejecuta (¿cambio de syntax?)

¡Gracias por adelantado!

¿Qué error obtiene con la consulta global de db en la pregunta SO vinculada? Intenta sustituir | para : en FOREACH , esa es la única diferencia de syntax de ruptura que puedo ver. La forma 2.x de decir lo mismo, excepto que se adapte a que tenga un solo tipo de relación en la base de datos, podría ser

 MATCH (a)-[r]->(b) WITH a, b, TAIL (COLLECT (r)) as rr FOREACH (r IN rr | DELETE r) 

Creo que el tubo WITH llevará las colas vacías cuando no haya duplicado, y no sé lo costoso que es recorrer una colección vacía; mi opinión es que el lugar para introducir el límite es con un filtro después del WITH , algo como

 MATCH (a)-[r]->(b) WITH a, b, TAIL (COLLECT (r)) as rr WHERE length(rr) > 0 LIMIT 100000 FOREACH (r IN rr | DELETE r) 

Dado que esta consulta no toca las propiedades en absoluto (a diferencia de la suya, que devuelve propiedades para (a) y (b)) no creo que deba tener mucha memoria para una gráfica mediana como la suya, pero tendrá Para experimentar con el límite.

Si la memoria sigue siendo un problema, entonces si hay alguna forma de limitar el funcionamiento de los nodos (sin tocar las propiedades), también es una buena idea. Si sus nodos son distinguibles por etiqueta, intente ejecutar la consulta para una etiqueta en ese momento

 MATCH (a:A)-[r]->(b) //etc.. MATCH (a:B)-[r]->(b) //etc.. 

Esta es una versión de la respuesta aceptada que se ha corregido (insertando la cláusula WITH rr ) para trabajar con las versiones más recientes de neo4j, y que debería ser más rápida (ya que solo crea la nueva lista de TAIL cuando sea necesario):

 MATCH (a)-[r]->(b) WITH a, b, COLLECT(r) AS rr WHERE LENGTH(rr) > 1 WITH rr LIMIT 100000 FOREACH (r IN TAIL(rr) | DELETE r); 

[ACTUALIZAR]

Si solo desea eliminar relaciones duplicadas con el mismo tipo , haga lo siguiente:

 MATCH (a)-[r]->(b) WITH a, b, TYPE(r) AS t, COLLECT(r) AS rr WHERE LENGTH(rr) > 1 WITH rr LIMIT 100000 FOREACH (r IN TAIL(rr) | DELETE r);