首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >WITH子句中的集合扩展为每行一个元素

WITH子句中的集合扩展为每行一个元素
EN

Stack Overflow用户
提问于 2018-09-19 16:57:06
回答 1查看 52关注 0票数 0

我想创建一个带有节点属性和一些附加信息的地图投影。我还想在一个集合中收集一些ID,并在稍后的查询中使用它来过滤掉节点(其中ID(n) in ids...)。地图投影是在apoc调用中创建的,其中包括几个联合匹配。

代码语言:javascript
复制
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部分时,它不会将"nodesWithAdditionalInfosIds“作为平面列表检查,而是每行只有一个id。这个问题之所以存在,是因为我在WITH子句中传递了ids (nodesWithAdditionalInfosIds)和nodeProjection (nodeWithInfo)。

如果我只使用id集合,而不使用nodeWithInfo投影,那么下面的调整会起作用,只返回id集合中id所在的节点:

代码语言:javascript
复制
...
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

如果我只是在两个示例中的WITH子句后面直接返回集合"nodesWithAdditionalInfosIds“,这就很明显了。因为第一个函数在一个结果行中生成了一个平面列表,第二个函数给出了每行一个id。

我有种感觉,我错过了关于neo4js With子句的关键知识。有没有一种方法可以传递我的listOfIds并将其用作平面列表,而不需要为集合使用独占的WITH子句?

编辑:现在我使用以下变通方法:在检查"n“和"u”的ID后,我不会返回,而是保留过滤后的"n“和"u”节点,并像以前一样开始第二个返回"nodeWithInfo“的apoc调用。

代码语言:javascript
复制
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中的if必须小心使用,如果有的话。在这种情况下,我只需要它们在这个查询中有效,所以下一次相同的节点是否有另一个id并不重要。

这个问题被剥离到核心问题(在我看来),原始的查询有点大,在apoc中有几个UNION匹配,并且在我的集合中包含in的节点上的实际匹配是检查一些更多的限制,而不是请求任何节点。

EN

回答 1

Stack Overflow用户

发布于 2018-09-20 07:36:56

COLLECT()一样,Aggregating functions也是在一组“分组键”上聚合的。

以下子句中的

使用collect(nodeWithInfo.id)作为nodesWithAdditionalInfosIds、nodeWithInfo

分组键为nodeWithInfo。因此,在下面的子句中,每个nodesWithAdditionalInfosIds始终是一个包含一个值的列表。

使用collect(nodeWithInfo.id)作为nodesWithAdditionalInfosIds

没有分组键。因此,在这种情况下,nodesWithAdditionalInfosIds将包含所有nodeWithInfo.id值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52401966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档