Neo4j Data Tidy Up - удаление дубликатов - PullRequest
0 голосов
/ 30 января 2020

Мне очень нравится Neo4j, но я застрял в этой маленькой проблеме. В моем графике есть узлы Mov ie, узлы актеров, узлы года и узлы компании. Некоторые узлы mov ie были продублированы из-за случайных орфографических ошибок. Например, «Одиннадцать океанов» и «Одиннадцать океанов» (обратите внимание на апостроф).

enter image description here

Поэтому мой вопрос: как мне дублировать все недостающие отношения? от "Одиннадцать океанов" до "Одиннадцати океанов", а затем удалить "Одиннадцать океанов"?

Мне нужен сценарий для запуска в каждом конкретном случае. Не беспокойтесь о применении этого также ко всем фильмам с апострофами, потому что ошибки в орфографии разные.

-

Обновление с примерами данных

MATCH (n) RETURN n LIMIT 25

Возвращает:

{"name":"Oceans Eleven","artwork":"oceans-eleven.jpg"}
{"name":"Brad Pitt","image":"brad-pitt.jpg"}
{"name":"George Clooney","image":"george-clooney.jpg"}
{"name":"Ocean's Eleven","artwork":"oceans-11.jpg"}
{"name":"2001"}
{"name":"Warner Brothers"}
{"name":"Matt Damon","image":"matt-damon.jpg"}
{"name":"Julia Roberts","image":"julia-roberts.jpg"}
{"name":"Netflix"}
{"name":"Andy Garcia","image":"andy-garcia.jpg"}

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Мне удалось объединить дублирующиеся узлы Neo4j следующим образом.

MATCH (fake:Production {name:"Oceans Eleven"})-[out]->(outNodes)
WITH outNodes, out
OPTIONAL MATCH (real:Production {name:"Ocean's Eleven"})
CALL apoc.create.relationship(real, type(out), properties(out), outNodes) YIELD rel
RETURN rel

Сначала скопируйте исходящие отношения.

MATCH (fake:Production {name:"Oceans Eleven"})<-[in]-(inNodes)
WITH inNodes, in
OPTIONAL MATCH (real:Production {name:"Ocean's Eleven"})
CALL apoc.create.relationship(inNodes, type(in), properties(in), real) YIELD rel
RETURN rel

Затем скопируйте входящие отношения.

MATCH (real:Production {name:"Ocean's Eleven"})-[r]-(b)
WITH real, b, TAIL (COLLECT (r)) as rr
FOREACH (r IN rr | DELETE r)

Удалите все вновь созданные повторяющиеся отношения.

MATCH (fake:Production {name:"Oceans Eleven"})
DETACH DELETE fake

И, наконец, удалите дублирующий узел.

0 голосов
/ 30 января 2020
MATCH (duplicateNode:Movie{name:"Oceans Eleven"})-[r]->(destNode)
WITH destNode , r  
OPTIONAL MATCH (trueNode:Movie{name:"Ocean's Eleven"})-[r1]->(destNode)
WHERE r1<>r 
WITH r1,r,destNode,trueNode
WITH r,trueNode,destNode, CASE r1 WHEN NULL THEN [] ELSE [1] END AS lst 
UNWIND lst as x
CALL apoc.create.relationship(trueNode,type(r),properties(r), destNode)
YIELD from,to 
RETURN from,to LIMIT 100

вышеупомянутый запрос создаст все внешние отношения.

MATCH (duplicateNode:Movie{name:"Oceans Eleven"})<-[r]-(destNode)
WITH destNode , r  
OPTIONAL MATCH (trueNode:Movie{name:"Ocean's Eleven"})<-[r1]-(destNode)
WHERE r1<>r 
WITH r1,r,destNode,trueNode
WITH r,trueNode,destNode, CASE r1 WHEN NULL THEN [1] ELSE [] END AS lst 
UNWIND lst as x
CALL apoc.create.relationship(destNode,type(r),properties(r), trueNode)
YIELD from,to 
RETURN from,to LIMIT 100

это будет делать внутренние отношения .. после выполнения двух выше для каждой ошибки. Вы можете сделать следующее, чтобы удалить все неправильные узлы

MATCH (movie:Movie) WHERE movie.name IN ["Oceans Eleven","..",".."] 
DETACH DELETE movie

, если дублирующие отношения узлов полностью отличаются от отношений исходного узла, тогда вы можете игнорировать следующую часть в приведенных выше сценариях,

OPTIONAL MATCH (trueNode:Movie{name:"Ocean's Eleven"})-[r1]->(destNode)
WHERE r1<>r 
WITH r1,r,destNode,trueNode
WITH r,trueNode,destNode, CASE r1 WHEN NULL THEN [] ELSE [1] END AS lst 
UNWIND lst as x

и просто сопоставьте trueNode

MATCH (trueNode:Movie{name:"Ocean's Eleven"})
...