Создать несколько уникальных отношений neo4j (один запрос) - PullRequest
0 голосов
/ 22 ноября 2018

В настоящее время я пишу плагин mongoose для автоматического поддержания узлов neo4j с использованием драйвера javascript neo4j и в настоящее время работаю над отображением обновлений (часть сохранения работает atm) в запрос шифрования.

В настоящее время я застрял в сценарии использования, в котором я хочу обновить несколько взаимосвязей между документом (a :Class, сохраненным как узел в neo4j) и обновленными ссылками (студенты типа :Person, сохраненныекак разные узлы в neo4j) при удалении старых связей, привязанных к старым ссылкам (студенты в данном случае).Это является результатом обновления массива ссылок на поддокументы в neo4j.

Основная проблема, помимо перекрестного (декартового) произведения, которое создается в запросе, состоит в том, что следующий запрос создает вдвое больше связей, чем он.удаляет:

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'}), 
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() 
WHERE type(r) IN ["HAS_STUDENT"] 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
DELETE r;

При этом удаляются 2 взаимосвязи (что правильно), но создаются 4 новые взаимосвязи (должно быть 2).

Также используется один CREATE в форме CREATE (I)<-[:HAS_STUDENT]-(doc)-[:HAS_STUDENT]->(II) не является допустимым параметром, так как этот запрос создается в цикле for и может содержать растущее количество новых отношений, которые будут созданы.(Также основная причина, почему я хочу оптимизировать запрос.)

У меня было несколько версий этого запроса, которые привели к одному и тому же результату.Проблема, вероятно, в части WHERE, потому что, когда я использую запрос ниже, он создает правильное количество отношений. Единственное, чего не хватает, так это того, что он должен удалять только старые отношения :

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'}) 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
WITH doc 
MATCH (doc)-[r]->(n) 
WHERE type(r) IN ["HAS_STUDENT"] 
DELETE r;

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

ПРИМЕЧАНИЕ: I и II будут позже использоваться в качестве переменных для назначения уникальных значений отношений, поэтому я не использовалодин MATCH для узлов :Person.

Кроме того, IN типа отношений в предложении WHERE используется из-за возможности создания различных типов отношений (и, таким образом,старые из этого типа удалены).

Наконец, я уже изучил UNWIND и FOREACH, но не могу вписать их в описанный вариант использования.

1 Ответ

0 голосов
/ 22 ноября 2018

Проблема с вашим шифром в том, что каждая операция выполняется за строку

Так что здесь

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), // 1
      (I:Person {m_id: '5bf5b9df11c344021de89393'}), // 1
      (II:Person {m_id: '5bf5b9df11c344021de89394'}), // 1
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() // 2
      // 1 match * 1 match  * 1 match * 2 match  = 2 rows
WHERE type(r) IN ["HAS_STUDENT"] 
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
// 2 create * 2 rows = 4 new relations
DELETE r;

Так что вам нужно вырезать «дубликат»строки, использующие DISTINCT перед созданием

MATCH (doc:Class {m_id: '5bf5b9df11c344021de89395'}), 
      (:Class {m_id: '5bf5b9df11c344021de89395'})-[r]->() 
WHERE type(r) IN ["HAS_STUDENT"] 
DELETE r;
WITH DISTINCT doc
MATCH (I:Person {m_id: '5bf5b9df11c344021de89393'}), 
      (II:Person {m_id: '5bf5b9df11c344021de89394'})
CREATE (doc)-[:HAS_STUDENT]->(I), (doc)-[:HAS_STUDENT]->(II) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...