Вы можете получить доступ к полю строки по их имени, поэтому вам не нужны клавиши UNWIND
on:
LOAD CSV WITH HEADERS FROM "file:///file.csv" AS row
WITH row
WHERE toInteger(row.sequence) = 0
MATCH (t:Group {ID: row.groupID})
MATCH (b:Element {ID: row.elementID})
MERGE (t)-[:STARTS]->(b);
Предположим, у вас есть индексы на :Group(ID)
и :Element(ID)
.Быть достаточно быстрым.
Используйте max
агрегацию, чтобы найти максимальный элемент и создать связь, это создает обе связи в одном запросе:
LOAD CSV WITH HEADERS FROM "file:/file.csv" as line
WITH line.groupID as groupID, collect({elementID: line.elementID, sequence:toInteger(line.sequence)}) as groupElements,max(toInteger(line.sequence)) as max
UNWIND groupElements as element
MATCH (g:Group {ID:groupID}),(e:Element {ID:element.elementID})
FOREACH(ignoreMe IN CASE WHEN element.sequence = 0 THEN [1] ELSE [] END | CREATE (g)-[:STARTS]->(e))
FOREACH(ignoreMe IN CASE WHEN element.sequence = max THEN [1] ELSE [] END | CREATE (g)-[:STOPS]->(e))
Используется описанный здесь трюк:
https://markhneedham.com/blog/2014/08/22/neo4j-load-csv-handling-empty-columns/
Обновление: Если у вас много строк с последовательностью, отличной от 0 и макс., Вы можете отфильтровать их, добавив
WITH element,max,groupID
WHERE element.sequence = 0 OR element.sequence = max
непосредственно перед MATCH
, что должно исключить поиск индекса для этих строк.
Обновление синтаксиса FOREACH / CASE : это обходной путь для недостатка возможностей Cypher в этомarea.
Выражение CASE - это условие Cypher if / then / else.Однако это выражение (= возвращает значение) и не может содержать операции записи.Вот для чего нам нужно FOREACH .
CASE WHEN element.sequence = 0 THEN [1] ELSE [] END
Возвращает массив, содержащий число 1, когда последовательность равна 0. Если условие последовательности истинно, оно будет эквивалентно этому:
FOREACH(ignoreMe IN [1] | CREATE (g)-[:STARTS]->(e))
Он выполнит часть после |
для каждого элемента в массиве.Переменная называется ignoreMe
, потому что она не используется.Если условие ложно, массив пуст, поэтому оператор CREATE выполняться не будет.