集合中元素的Neo4j Cypher查询和索引
我试图通过集合中元素的Neo4j Cypher查询和索引,neo4j,cypher,Neo4j,Cypher,我试图通过{decisionGroupId},{decisionId}和{criteriaid}查找决策的索引号 这是我当前的密码查询: MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision) WHERE dg.id = {decisionGroupId} OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion) WHERE c.id IN {criteriaIds}
{decisionGroupId}
,{decisionId}
和{criteriaid}
查找决策的索引号
这是我当前的密码查询:
MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision)
WHERE dg.id = {decisionGroupId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion)
WHERE c.id IN {criteriaIds}
WITH childD, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes
ORDER BY weight DESC, totalVotes DESC
WITH COLLECT(childD) AS ps
RETURN REDUCE(ix = -1, i IN RANGE(0, SIZE(ps)-1)
| CASE ps[i].id WHEN {decisionId} THEN i ELSE ix END) AS ix
我在数据库中只有3个Decision,但此查询返回以下索引:
2
3
4
而我期望类似(如果未找到,则从0和-1开始)
我的查询有什么问题,如何解决
已更新
此查询在将COLLECT(DISTINCT childD)作为ps时运行良好
:
MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision)
WHERE dg.id = {decisionGroupId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion)
WHERE c.id IN {criteriaIds}
WITH childD, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes
ORDER BY weight DESC, totalVotes DESC
WITH COLLECT(DISTINCT childD) AS ps
RETURN REDUCE(ix = -1, i IN RANGE(0, SIZE(ps)-1)
| CASE ps[i].id WHEN {decisionId} THEN i ELSE ix END) AS ix
请帮助我重构此查询并摆脱繁重的REDUCE让我们用一个更简单的查询来尝试正确处理REDUCE
部分:
WITH ['a', 'b', 'c'] AS ps
RETURN
reduce(ix = -1, i IN RANGE(0, SIZE(ps)-1) |
CASE ps[i] WHEN 'b' THEN i ELSE ix END) AS ix
)
如我在评论中所述,如果可能,通常最好避免reduce
。因此,要使用a表示相同的值,请使用WHERE
进行过滤
WITH ['a', 'b', 'c'] AS ps
RETURN [i IN RANGE(0, SIZE(ps)-1) WHERE ps[i] = 'b'][0]
列表理解将生成一个包含单个元素的列表,我们将使用[0]
索引器选择该元素
根据您的查询调整后,我们将得到如下结果:
MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision)
WHERE dg.id = {decisionGroupId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion)
WHERE c.id IN {criteriaIds}
WITH childD, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes
ORDER BY weight DESC, totalVotes DESC
WITH COLLECT(DISTINCT childD) AS ps
RETURN [i IN RANGE(0, SIZE(ps)-1) WHERE ps[i].id = {decisionId}][0]
如果安装了APOC,还可以使用以下功能:
返回apoc.coll.indexOf([1,2,3],2)
非常强大,实际上只有在极少数情况下,当您需要使用累加器变量的状态时才需要它。在这里,我首先尝试一个:返回[I在范围内(0,大小(ps)-1)| CASE ps[I].id当{decisionId}然后I ELSE-1 END]作为ix时会得到什么结果呢
谢谢,在提供的模式理解中,它返回类似于这样的东西[-1,1,2,-1,-1]
,而不是确切的索引这很奇怪。如果RETURN childD
返回3行,将其更改为,以collect(childD)作为ps RETURN[i在范围(0,SIZE(ps)-1)内| CASE ps[i].id当{decisionId}那么i ELSE-1 END]作为ix
应该返回一个包含3项的列表。好的,现在我明白为什么使用reduce了。我马上补充一个答案。非常感谢!现在它像一个魅力!谢谢你的回答。从性能的角度来看——最好的方式是什么——纯密码或APOC功能?我认为最常见的是APOC
MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision)
WHERE dg.id = {decisionGroupId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion)
WHERE c.id IN {criteriaIds}
WITH childD, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes
ORDER BY weight DESC, totalVotes DESC
WITH COLLECT(DISTINCT childD) AS ps
RETURN [i IN RANGE(0, SIZE(ps)-1) WHERE ps[i].id = {decisionId}][0]