我想创建一个带有节点属性和一些附加信息的地图投影。我还想在一个集合中收集一些ID,并在稍后的查询中使用它来过滤掉节点(其中ID(n) in ids...)。地图投影是在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部分时,它不会将"nodesWithAdditionalInfosIds“作为平面列表检查,而是每行只有一个id。这个问题之所以存在,是因为我在WITH子句中传递了ids (nodesWithAdditionalInfosIds)和nodeProjection (nodeWithInfo)。
如果我只使用id集合,而不使用nodeWithInfo投影,那么下面的调整会起作用,只返回id集合中id所在的节点:
...
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调用。
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的节点上的实际匹配是检查一些更多的限制,而不是请求任何节点。
发布于 2018-09-20 07:36:56
与COLLECT()
一样,Aggregating functions也是在一组“分组键”上聚合的。
以下子句中的
使用collect(nodeWithInfo.id)作为nodesWithAdditionalInfosIds、nodeWithInfo
分组键为nodeWithInfo
。因此,在下面的子句中,每个nodesWithAdditionalInfosIds
始终是一个包含一个值的列表。
使用collect(nodeWithInfo.id)作为nodesWithAdditionalInfosIds
没有分组键。因此,在这种情况下,nodesWithAdditionalInfosIds
将包含所有nodeWithInfo.id
值。
https://stackoverflow.com/questions/52401966
复制相似问题