Коллекция в предложении WITH расширяется до одного элемента в строке - PullRequest
0 голосов
/ 19 сентября 2018

Я хочу создать картографическую проекцию со свойствами узла и некоторой дополнительной информацией.Также я хочу собрать некоторые идентификаторы в коллекции и использовать это позже в запросе для фильтрации узлов (где 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, и фактическое совпадение узлов, идентификаторы которых содержатся в моей коллекции, проверяет некоторые дополнительные ограничения, а не запрашивает какой-либо узел.

1 Ответ

0 голосов
/ 20 сентября 2018

Агрегирующие функции , такие как COLLECT(), агрегирование по набору "ключей группировки" .

  • В следующем пункте:

     WITH collect(nodeWithInfo.id) as nodesWithAdditionalInfosIds, nodeWithInfo
    

    ключ группировки - nodeWithInfo.Следовательно, каждый nodesWithAdditionalInfosIds всегда будет списком, содержащим одно значение.

  • И в следующем предложении:

    WITH collect(nodeWithInfo.id) as nodesWithAdditionalInfosIds
    

    ключ группировки отсутствует.Следовательно, в этой ситуации nodesWithAdditionalInfosIds будет содержать все значения nodeWithInfo.id.

...