Вы здесь очень близки, у вашего Cypher есть решение, которое вам нужно:
MERGE (sy)-[:CONTAINS_DATASET]->(dan:Dataset { name: datasets.name })
Этот шаблон имеет связанную (ранее сопоставленную с элементом графика) переменную sy
и несвязанную (ранее не сопоставленную ни с чем, первое вхождение в запросе) переменную dan
.
MERGE похож на выполнение МАТЧИ паттерна, и тогда поведение будет меняться в зависимости от того, существует ли этот паттерн на графике или нет.
Если он существует в графе (sy
имеет отношение: CONTAINS_DATASET к узлу: Dataset с заданным именем), он будет повторно использовать существующие структуры графа, и dan
будет привязан к этому существующему подключенному узлу.
Если он не существует в графе, будет создан весь шаблон, и это будет включать создание любых не связанных ранее узлов, например, dan
. Если шаблон не существует, он заблокирует связанные части шаблона (sy
), дважды проверит, чтобы убедиться, что ничего не изменилось между временем, когда он проверил, и временем, которое потребовалось, и затем это создаст части шаблона, которые ранее не были связаны. sy
был ранее связан, поэтому он будет использовать этот же узел вместо создания нового. (dan:Dataset { name: datasets.name })
ранее не был связан, поэтому новый узел с этой меткой и этим свойством будет создан и подключен к sy
через отношение: CONTAINS_DATASET.
Таким образом, это поведение должно быть именно тем, что вам нужно: повторно использовать подключенный узел с таким именем, если он существует, или создать новый узел с этим именем и подключить его к sy
узлу.
Что касается дубликатов, которые вы видите, то это из-за строки перед ней:
MERGE (da:Dataset { name: datasets.name})
Здесь это не нужно, вы уже удовлетворяете свои потребности с помощью строки после нее, поэтому удалите ее, и ваш запрос должен работать на вас.
Подробнее о поведении MERGE в нашей статье базы знаний .