Я хочу создать картографическую проекцию со свойствами узла и некоторой дополнительной информацией.Также я хочу собрать некоторые идентификаторы в коллекции и использовать это позже в запросе для фильтрации узлов (где ID (n) в идентификаторах ...).Проекция карты создается в вызове apoc, который включает в себя несколько совпадений объединений.
call apoc.cypher.run('MATCH (n)-[:IS_A]->({name: "User"}) MATCH (add)-[:IS_A]->({name: "AdditionalInformationForUser"}) RETURN n{.*, info: collect(add.name), id: ID(n)} as nodeWithInfo UNION MATCH (n)-[:IS_A]->({Department}) MATCH (add)-[:IS_A]->({"AdditionalInformationForDepartment"}) RETURN n{.*, info: collect(add.name), id: ID(n)} as nodeWithInfo', NULL) YIELD value
WITH (value.nodeWithInfo) AS nodeWithInfo
WITH collect(nodeWithInfo.id) as nodesWithAdditionalInfosIds, nodeWithInfo
MATCH (n)-[:has]->({"Vacation"})
MATCH (u)-[:is]->({"Out of Order"})
WHERE ID(n) in nodesWithAdditionalInfosIds and ID(u) in nodesWithAdditionalInfosIds
return n, u, nodeWithInfo
Это ничего не возвращает, потому что, когда часть where оценивается, она не проверяет "nodeWithAdditionalInfosIds" как плоский список, новместо этого получает только один идентификатор в строке.Проблема существует только потому, что я передаю идентификаторы (nodeWithAdditionalInfosIds) И nodeProjection (nodeWithInfo) в предложении WITH.
Если вместо этого я использую только коллекцию идентификаторов и не использую проекцию nodeWithInfo, то следующая корректировкаработает и возвращает только те узлы, идентификаторы которых находятся в коллекции идентификаторов:
...
WITH collect(nodeWithInfo.id) as nodesWithAdditionalInfosIds
MATCH (n)-[:has]->({"Urlaub"})
MATCH (u)-[:is]->({"Out of Order"})
WHERE ID(n) in nodesWithAdditionalInfosIds and ID(u) in nodesWithAdditionalInfosIds
return n, u
Если я просто верну коллекцию "nodeWithAdditionalInfosIds" непосредственно после предложения WITH в обоих примерах, это становится очевидным.Поскольку первый генерирует плоский список в одной строке результатов, а второй дает мне один идентификатор на строку.
У меня такое ощущение, что мне не хватает важных знаний о предложении neo4js With.Есть ли способ передать мой listOfIds и использовать его как плоский список без необходимости иметь эксклюзивное предложение WITH для коллекции?
edit: сейчас я использую следующий обходной путь: после того, как япроверку идентификаторов «n» и «u» я не возвращаю, но вместо этого сохраняю отфильтрованные узлы «n» и «u» и запускаю второй вызов apoc, который возвращает «nodeWithInfo», как раньше.
WITH n, u
call apoc.cypher.run('MATCH (n)-[:IS_A]->({name: "User"}) MATCH (add)-[:IS_A]->({name: "AdditionalInformationForUser"}) RETURN n{.*, info: collect(add.name), id: ID(n)} as nodeWithInfo UNION MATCH (n)-[:IS_A]->({Department}) MATCH (add)-[:IS_A]->({"AdditionalInformationForDepartment"}) RETURN n{.*, info: collect(add.name), id: ID(n)} as nodeWithInfo', NULL) YIELD value
WITH (value.nodeWithInfo) AS nodeWithInfo, n, u
WHERE nodeWithInfo.id = ID(n) OR nodeWithInfo.id = ID(u)
RETURN nodeWithInfo, n, u
Таким образом, я могу вернуть узлы n, u и дополнительную информацию (одному из узлов) для каждой строки.Но я уверен, что должен быть лучший способ.
Я знаю, что идентификаторы в neo4j должны использоваться с осторожностью, если они вообще нужны.В этом случае мне нужно, чтобы они были действительными только в этом запросе, поэтому не имеет значения, будет ли следующий раз у того же узла другой идентификатор.
Проблема сведена к основной проблеме (по моему мнению), исходный запрос немного больше с несколькими UNION MATCH внутри apoc, и фактическое совпадение узлов, идентификаторы которых содержатся в моей коллекции, проверяет некоторые дополнительные ограничения, а не запрашивает какой-либо узел.