Почему мой вызов apo c .refactor.cloneNodes итерирует и создает клоны для каждого узла в графе? - PullRequest
1 голос
/ 21 января 2020

Я намеревался клонировать один узел и его 3 соединения, но в итоге получилось несколько клонов.

Сначала сопоставив весь граф первичного узла и связанных узлов, когда я вызываю apo c .refactor .cloneNodes, кажется, перебирает каждый связанный узел, а не только основной узел, который я хочу клонировать. Результатом является исходный первичный узел и 3 клона (вместо предполагаемого 1 клона), связанные с ожидаемыми связанными узлами.

. , .

Я создал этот игрушечный граф:

create (a:Node {description:"Spider Man Series"})
create (b:Node {description:"Spidey"})
create (c:Node {description:"Doc Oc"})
create (d:Node {description:"Venom"})
create (a)-[:BELONGS]->(b)
create (a)-[:BELONGS]->(c)
create (a)-[:BELONGS]->(d)
return a,b,c,d

Я хочу клонировать «Человека-паука» (и его отношения):

match (a)-[c]-(b)
where a.description="Spider Man Series"
call apoc.refactor.cloneNodes([a],true) yield output
return a,b,c, output

Но это создает 3 клоны (по одному на каждый связанный символьный узел). Я предполагаю, что это как-то связано с тем, что у MATCH есть отношения.

Потому что, если я просто ограничу свой MATCH без отношений, я получу правильное поведение клона (оригинальная «Серия Человек-паук» и клон «Человек-паук» с клонированными связями). Я в замешательстве, потому что есть только 1 узел, полученный в результате предложения WHERE, который хранится в (a).

match (a)
where a.description="Spider Man Series"
call apoc.refactor.cloneNodes([a],true) yield output
return a,output

. , .

Я пытался ограничить связанные узлы до 2 вместо всего, к чему был подключен «Spider Man Series», но это ТАКЖЕ дало мне клон для каждого связанного узла:

match (a)-[c]-(b)
where a.description="Spider Man Series" and b.description in ['Spidey','Venom']
call apoc.refactor.cloneNodes([a],true) yield output
return a,b,c, output

1 Ответ

1 голос
/ 21 января 2020

apoc.refactor.cloneNodes возьмет узлы, которые вы ему дадите, и создаст их копии, копируя отношения из старых узлов в новые узлы, если вы дадите ему true в качестве второго параметра.

You ' Вы видите дублирование, потому что, как вы говорите, из этого первого запроса возвращается несколько строк - один из подходов состоит в DISTINCT a узлах до того, как вы сделаете клон:

match (a)-[c]-(b)
where a.description="Spider Man Series"
WITH distinct a as da
call apoc.refactor.cloneNodes([da],true) yield output
return output

enter image description here

Однако, если вы хотите создать полную копию подграфа, то есть иметь два узла «Человек-паук», и у каждого есть три узла символов, но эти два подграфа не связаны тогда что-то вроде apoc.refactor.cloneSubgraphFromPaths будет работать лучше:

match path=(a)-[c]-(b)
where a.description="Spider Man Series"
with collect(path) as paths
call apoc.refactor.cloneSubgraphFromPaths(paths) YIELD output
return output

enter image description here

...