Neo4j Cypher查询和节点参数而不是关系值

时间:2017-06-12 22:39:52

标签: neo4j cypher spring-data-neo4j neo4j-ogm

在我的Neo4j,SDN4项目中,我有以下实体:

DecisionCriterionVote

每个决定都可以对不同的标准进行投票。

现在我使用以下Cypher查询来按平均排序决策。所选条件的投票权重({criteriaIds}参数代表Set<Long>个ID的Criterion

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

现在我对此查询的性能不满意,所以我想在查询执行期间减少数据基数。

为了做到这一点,我不打算将每个avgVotesWeight存储为DecisionCriterion之间关系的属性,而是计划将此值存储为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 ConverterDecision中的其余1属性区分开来,或者23后缀为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值,这些值当前也存储在DecisionCriterion之间的相同关系中。请指教。也许它应该以我想要为avgVotesWeight实现的相同方法存储?例如,我可以引入Decision之类的附加TV1=34属性。这是个好主意吗?

1 个答案:

答案 0 :(得分:0)

对于可能对类似解决方案感兴趣的人,这是我的新工作查询:

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