我正在尝试查找 Decision
的索引号通过{decisionGroupId}
, {decisionId}
和{criteriaIds}
这是我当前的 Cypher 查询:
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 个决策,但此查询返回以下索引:
2
3
4
虽然我期待类似的东西(如果没有找到,则从 0 开始,从 -1 开始)
0
1
2
我的查询有什么问题以及如何修复它?
已更新
此查询与 COLLECT(DISTINCT childD) AS 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
。因此,使用 list comprehension 来表达相同的内容,使用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]
关于Neo4j Cypher 查询和集合中元素的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47378187/