У нас есть узлы, организованные в виде дерева (((: Object) - [: PARENT] -> (: Object))
Объект может использовать множество Item ({: Object) - [: USE] -> (: Item))
Мы бы хотели воспроизвести правило наследования:
если родитель использует один элемент, а у сына нет элемента с такими же свойствами => сын будет использовать элемент родителя.
Следующий код работает нормально, но очень медленно работает на больших наборах (у нас есть около 4 тыс. Объектов, у объекта может быть 2 тыс. Использования)
MATCH (p:Object)
WHERE p.rank = 1
WITH p
MATCH (p)-[:PARENT]->()-[:USE]->(used)
WHERE NOT exists((p)-[:USE]->(:Item {
property1:used.property1,
property2:used.property2,
property3:used.property3}))
MERGE (p)-[:USE]->(used);
У вас есть лучшее решение?
- ОБНОВЛЕНИЕ -
После изучения кажется, что медлительность связана с размером транзакции (мы добавляем несколько миллионов отношений).
Итак, мы сейчас ищем способразделить транзакцию, чтобы получить что-то вроде этого:
DO {
MATCH (p:Object)
WHERE p.rank = 1 AND p.updated IS null
WITH p LIMIT 50
MATCH (p)-[:PARENT]->()-[:USE]->(item)
WHERE NOT exists((p)-[:USE]->(:Item {
property1:item.property1,
property2:item.property2,
property3:item.property3}))
MERGE (p)-[:USE]->(item)
SET p.updated=true
COMMIT
} WHILE(something updated)
В настоящее время мы нашли единственный способ сделать внешние сценарии (powershell или python).
Возможно ли это сделать в Cypher?