Neo4j Cypher 查询和节点参数而不是关系值
Neo4j Cypher query and node parameters instead of relationship values
在我的 Neo4j、SDN4 项目中,我有以下实体:
Decision
、Criterion
、Vote
每个决定都可以对不同的标准进行投票。
现在我使用以下 Cypher 查询来按平均值对决策进行排序。所选标准的投票权重({criteriaIds}
参数表示 Criterion
个 ID 中的 Set<Long>
个):
MATCH (parentD)-[:CONTAINS]->(childD:Decision)
WHERE id(parentD) = {decisionId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c)
WHERE id(c) IN {criteriaIds}
WITH c, childD, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User)
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes
ORDER BY weight DESC, childD.name ASC
SKIP 0 LIMIT 10
现在我对这个查询的性能不满意,所以我想在查询执行期间减少数据基数。
为了做到这一点,我计划将此值存储为
和 Criterion
之间的关系,而不是将每个 avgVotesWeight
存储为 属性 =69=] Decision
节点本身。
例如我有以下节点:
Decision1(uid = 1)
Criterion1(uid = 1)
Criterion2(uid = 2)
Criterion3(uid = 3)
Decision1
有以下 avgVotesWeight
条件:
Decision1 for Criterion1 = 4.3
Decision2 for Criterion1 = 2.1
Decision3 for Criterion1 = 1.8
所以我要在 Decision1
节点上创建以下属性:
Decision1(CAVW1=4.3, CAVW2=2.1, CAVW3=1.8)
其中 CAVW
是一个普通的 String
前缀,以便将这些属性与我的 SDN4 Custom Type Converter 和 [=31= 中的其他 Decision
属性区分开来] 或 2
或 3
后缀是 Criterion
uid
(我将这些 uid
传递给 {criteriaIds}
参数中的 Cypher 查询)
所以我的问题是 - 总的来说这是个好主意吗?如果是这样,您能否帮我重写上面提到的查询,以便使用这些属性而不是以下旧的 Cypher 查询:
WHERE id(c) IN {criteriaIds}
WITH c, childD, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes
此外,我现在不知道将 vg.totalVotes
值保存在何处,这些值当前也存储在 Decision
和 Criterion
之间的相同关系中。请指教。也许它也应该像我想为 avgVotesWeight
实现的那样使用相同的方法存储?例如,我可以引入 Decision
属性,例如 TV1=34
。这是个好主意吗?
对于可能对类似解决方案感兴趣的人,这是我的新工作查询:
MATCH (parentD)-[:CONTAINS]->(childD:Decision)
WHERE id(parentD) = {decisionId}
UNWIND {criteriaIds} AS cid
WITH childD, (properties(childD)['CAVW' + cid] * (CASE WHEN cid IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(cid)], 1.0) ELSE 1.0 END)) AS weight, properties(childD)['CTV' + cid] AS totalVotes
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User)
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes
ORDER BY weight
DESC SKIP 0 LIMIT 2
在我的 Neo4j、SDN4 项目中,我有以下实体:
Decision
、Criterion
、Vote
每个决定都可以对不同的标准进行投票。
现在我使用以下 Cypher 查询来按平均值对决策进行排序。所选标准的投票权重({criteriaIds}
参数表示 Criterion
个 ID 中的 Set<Long>
个):
MATCH (parentD)-[:CONTAINS]->(childD:Decision)
WHERE id(parentD) = {decisionId}
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c)
WHERE id(c) IN {criteriaIds}
WITH c, childD, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User)
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes
ORDER BY weight DESC, childD.name ASC
SKIP 0 LIMIT 10
现在我对这个查询的性能不满意,所以我想在查询执行期间减少数据基数。
为了做到这一点,我计划将此值存储为
和 Criterion
之间的关系,而不是将每个 avgVotesWeight
存储为 属性 =69=] Decision
节点本身。
例如我有以下节点:
Decision1(uid = 1)
Criterion1(uid = 1)
Criterion2(uid = 2)
Criterion3(uid = 3)
Decision1
有以下 avgVotesWeight
条件:
Decision1 for Criterion1 = 4.3
Decision2 for Criterion1 = 2.1
Decision3 for Criterion1 = 1.8
所以我要在 Decision1
节点上创建以下属性:
Decision1(CAVW1=4.3, CAVW2=2.1, CAVW3=1.8)
其中 CAVW
是一个普通的 String
前缀,以便将这些属性与我的 SDN4 Custom Type Converter 和 [=31= 中的其他 Decision
属性区分开来] 或 2
或 3
后缀是 Criterion
uid
(我将这些 uid
传递给 {criteriaIds}
参数中的 Cypher 查询)
所以我的问题是 - 总的来说这是个好主意吗?如果是这样,您能否帮我重写上面提到的查询,以便使用这些属性而不是以下旧的 Cypher 查询:
WHERE id(c) IN {criteriaIds}
WITH c, childD, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes
此外,我现在不知道将 vg.totalVotes
值保存在何处,这些值当前也存储在 Decision
和 Criterion
之间的相同关系中。请指教。也许它也应该像我想为 avgVotesWeight
实现的那样使用相同的方法存储?例如,我可以引入 Decision
属性,例如 TV1=34
。这是个好主意吗?
对于可能对类似解决方案感兴趣的人,这是我的新工作查询:
MATCH (parentD)-[:CONTAINS]->(childD:Decision)
WHERE id(parentD) = {decisionId}
UNWIND {criteriaIds} AS cid
WITH childD, (properties(childD)['CAVW' + cid] * (CASE WHEN cid IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(cid)], 1.0) ELSE 1.0 END)) AS weight, properties(childD)['CTV' + cid] AS totalVotes
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User)
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes
ORDER BY weight
DESC SKIP 0 LIMIT 2