Neo4j Cypher查询和复杂排序

时间:2017-02-18 23:21:21

标签: neo4j cypher

我有以下Cypher查询:

MATCH (t:Tenant) WHERE ID(t) in {tenantIds} 
 OR t.isPublic 
WITH COLLECT(t) as tenants 
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
 AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
   OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
 AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
   OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t)))  
MATCH (childD)<-[:SET_FOR]-(filterValue630:Value)-[:SET_ON]->(filterCharacteristic630:Characteristic) 
WHERE id(filterCharacteristic630) = 630 
WITH filterValue630, childD, ru, u 
WHERE  (filterValue630.value <= 799621200000)  
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue631:Value)-[:SET_ON]->(sortCharacteristic631:Characteristic) 
WHERE id(sortCharacteristic631) = 631 
RETURN ru, u, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
 | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
 | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
 | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
ORDER BY sortValue631.value ASC, childD.createDate DESC 
SKIP 0 LIMIT 100

作为此查询执行的结果,我收到15条记录,其中每条记录都正确包含已填充的commentGroupsweightedCriteriavaluedCharacteristics个集合。

但是当我将查询更改为以下内容时(我按标准权重添加排序条件):

MATCH (t:Tenant) 
WHERE ID(t) in {tenantIds} 
 OR t.isPublic 
WITH COLLECT(t) as tenants 
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
 AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
  OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
 AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
  OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t)))  
MATCH (childD)<-[:SET_FOR]-(filterValue630:Value)-[:SET_ON]->(filterCharacteristic630:Characteristic) 
WHERE id(filterCharacteristic630) = 630 
WITH filterValue630, childD, ru, u 
WHERE  (filterValue630.value <= 799621200000)  
OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
WHERE id(c) IN {criteriaIds} 
WITH c, childD, ru, u, (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 
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue631:Value)-[:SET_ON]->(sortCharacteristic631:Characteristic) 
WHERE id(sortCharacteristic631) = 631 
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue631, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
 | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
 | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
 | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
ORDER BY  weight DESC,  totalVotes ASC, sortValue631.value ASC, childD.createDate DESC 
SKIP 0 LIMIT 100

查询无误地运行并返回15条记录的相同结果集,但commentGroupsweightedCriteriavaluedCharacteristics个集合仅填充weight > 0其余部分为null

这是错误的,并不像预期的那样。应为第一次查询执行后的结果集中的所有记录填充commentGroupsweightedCriteriavaluedCharacteristics个集合。

现在我不明白为什么新的Cypher查询的以下部分会妨碍上述集合的正确填充:

OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
WHERE id(c) IN {criteriaIds} 
WITH c, childD, ru, u, (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 

我在新查询中做错了什么以及如何修复它?

已更新

这是产生问题的查询:

MATCH (t:Tenant) WHERE ID(t) in [] 
  OR t.isPublic 
  WITH COLLECT(t) as tenants 
  MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
  WHERE id(parentD) = 60565 
    AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
      OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
    AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
      OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t)))  
  MATCH (childD)<-[:SET_FOR]-(filterValue60639:Value)-[:SET_ON]->(filterCharacteristic60639:Characteristic) 
  WHERE id(filterCharacteristic60639) = 60639 
  WITH filterValue60639, childD, ru, u 
  WHERE  (filterValue60639.value <= 799621200000)  
  OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
  WHERE id(c) IN [60581, 60575] 
  WITH childD, ru, u, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes 
  OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue60640:Value)-[:SET_ON]->(sortCharacteristic60640:Characteristic) 
  WHERE id(sortCharacteristic60640) = 60640 
  RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640, 
  [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
  [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
    | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
  [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
    | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
  ORDER BY  weight DESC,  totalVotes ASC, sortValue60640.value ASC, childD.createDate DESC 
  SKIP 0 LIMIT 100

出于某种原因

  OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
  WHERE id(c) IN [60581, 60575] 

阻止与此表达式不匹配的所有commentGroups的{​​{1}},weightedCriteriavaluedCharacteristics个收集人群。如何解决此问题?

enter image description here

1 个答案:

答案 0 :(得分:2)

好的,这是一件相当奇怪的事情。我找到了一些应该有用的东西,虽然目前我不知道它为什么有效,只是它涉及在你返回之前计算重量和总体数。

取你的RETURN的第一行,并用它替换它,首先包括一个WITH子句,它将计算权重和totalVotes,然后执行RETURN:

WITH ru, u, childD, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640
RETURN ru, u, childD AS decision, weight, totalVotes, sortValue60640,

另外需要注意的是,在执行模式推导之前,可以通过执行ORDER BY,SKIP和LIMIT操作来保存一些不必要的操作:

WITH ru, u, childD, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640
ORDER BY  weight DESC,  totalVotes ASC, sortValue60640.value ASC, childD.createDate DESC 
  SKIP 0 LIMIT 100
RETURN ru, u, childD AS decision, weight, totalVotes, sortValue60640,
  [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: id(entity),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
  [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
    | {criterionId: id(c1),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
  [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
    | {characteristicId: id(ch1),  value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics