【问题标题】:Neo4j Cypher query and complex sortingNeo4j Cypher 查询和复杂排序
【发布时间】:2017-02-18 23:21:21
【问题描述】:

我有以下 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 &gt; 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] 

防止commentGroupsweightedCriteriavaluedCharacteristics 收集与此表达式不匹配的所有childD。如何解决此问题?

【问题讨论】:

  • 如果您可以进一步剥离查询并提供一个最小数据集来演示它并通过console.neo4j.org分享它会很好。
  • 我找不到如何在 Windows 平台下将数据库转储到 Cypher 脚本以便加载到 console.neo4j.org 的信息
  • @StefanArmbruster 我已经用我的测试数据库转储更新了我的问题。不幸的是,我找不到将其上传到 console.neo4j.org 的方法,所以我已将数据库转储到文件系统。
  • 第二天我在处理这个查询,不明白 OPTIONAL MATCH (childD)&lt;-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]-&gt;(c:Criterion) WHERE id(c) IN [60581, 60575] 如何影响模式理解,例如 [ (parentD)&lt;-[:DEFINED_BY]-(ch1:Characteristic)&lt;-[rso:SET_ON]-(v1:Value)-[rsf:SET_FOR]-&gt;(childD) | {characteristicId: id(ch1), value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 以及如何解决它。
  • 转储中的数据库受密码保护,默认的 neo4j/neo4j 不起作用。

标签: neo4j cypher


【解决方案1】:

好吧,这是一件很奇怪的事情。我发现了一些应该有效的方法,但目前我无法说明它为什么有效,只是它涉及在您返回之前计算重量和总投票数。

取您的 RETURN 的第一行,并将其替换为 this,其中首先包含一个 WITH 子句,它将计算 weight 和 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 

【讨论】:

  • 非常感谢您的帮助!一切都像魅力一样运作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2022-11-26
  • 2015-11-01
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多