如何在Cypher中将两个查询的结果集用作第三个查询的参数?

时间:2018-05-28 22:19:19

标签: neo4j cypher graph-databases

你好Neo4J / Cypher Gurus。

我需要获取两个查询的结果集,并将它们用作第三个查询的参数。 我能够使用一个(或另一个)查询的resut集作为第三个查询的参数,但是同一时间的两个查询都不起作用。

我正在尝试:

// External Parameter
:params {extParam:'1.1.1'}
// First Query
MATCH p=(startnode:DerivTree)-[:IsDerivedFrom*0..]->(endnode:DerivTree)
  WHERE startnode.dbvid=$extParam
  UNWIND nodes(p) as query1_list
  WITH distinct query1_list.dbvid as query1_result
// Second Query
MATCH (d:Resource {deleted:true})
  WHERE d.dbvid=$extParam
  WITH COLLECT(d) AS query2_list
  UNWIND query2_list as query2_result
// Third Query
MATCH (n:Resource)
  WHERE n.prop1 = query1_result
    AND n.prop2 <> query2_result
    AND EXISTS(n.prop3)
  RETURN n

如果我尝试查询1和查询3(没有使用查询2结果集的过滤器),它可以工作。 如果我尝试查询2和查询3(没有使用查询1结果集的过滤器),它也可以工作。

但我需要查询3的过滤器上的查询1和2结果集。

有任何线索吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

您在变量之间创建笛卡尔积。如果您对查询进行概况分析,您应该看到在查询过程中,操作之间流动的行数会增加。

此外,由于您未在第二个查询中将其包含在WITH中,因此您将query1_result删除了范围。改变了范围内的内容;如果你想让它继续在范围内,你需要包括它。

要解决此问题,您可能希望确保在整个过程中收集结果(例如收集第一个查询的结果,以便基数降至1以避免乘法执行下一个操作),然后执行此操作对于查询2也是如此,如果您确实需要将结果作为行,请为查询3展开它们(尽管在您的情况下使用in列表成员资格应该足够了。)

尝试一下:

// First Query
MATCH p=(startnode:DerivTree)-[:IsDerivedFrom*0..]->(endnode:DerivTree)
WHERE startnode.dbvid=$extParam
UNWIND nodes(p) as query1 // this is not a list, so rename the variable
WITH collect(distinct query1.dbvid) as query1_results // cardinality at 1 row
// Second Query
MATCH (d:Resource {deleted:true})
WHERE d.dbvid=$extParam
WITH query1_results, COLLECT(d) AS query2_results // cardinality at 1 row
// Third Query
MATCH (n:Resource)
WHERE n.prop1 in query1_results
  AND not n.prop2 in query2_results
  AND EXISTS(n.prop3)
RETURN n