【问题标题】:Cypher to return total node count as well as a limited setCypher 返回总节点数以及有限集
【发布时间】:2015-03-04 12:12:53
【问题描述】:

是否可以在单个密码查询中提取有限的节点集和节点总数?

match (n:Molecule) with n, count(*) as nb limit 10 return {N: nb, nodes: collect(n)}

上述查询正确返回节点,但返回 1 作为节点数。我当然明白为什么它返回 1,因为没有分组,但不知道如何纠正它。

【问题讨论】:

  • 是否可以将其与where 语句结合使用?基本上,我不想要总节点数。我想要满足“某些”条件的节点数。

标签: neo4j cypher


【解决方案1】:

以下查询返回全部行数的计数器(我猜这是需要的)。然后它再次匹配并限制您的搜索,但原始计数器仍然可用,因为它是通过WITH-statement 进行的。

MATCH 
    (n:Molecule)
WITH 
    count(*) AS cnt
MATCH 
    (n:Molecule)
WITH 
    n, cnt LIMIT 10
RETURN 
    { N: cnt, nodes:collect(n) } AS molecules

【讨论】:

  • 如果 MATCH 真的很复杂怎么办?复制它会导致性能损失,还是 Neo4j 足够聪明,可以重用第一次匹配的结果?
  • 刚刚用一个非常重的匹配测试了这个。不,Neo4j 不够聪明。没有计数部分需要 44-45 秒,计数是 89-90 秒。这就像运行查询两次,所以不需要真正组合查询......@SzczepanHołyszewski
【解决方案2】:

这是一个替代解决方案:

match (n:Molecule) return {nodes: collect(n)[0..5], n: length(collect(n))}

30k 节点为 84 毫秒,比 wassgren 提出的上述节点更短但效率不高。

【讨论】:

  • 它可能比以前的解决方案更多的内存。我们在这里谈论的是包含分子描述的数百万个分子节点(SMILES 字符串、INCHI 键、分子 PNG 的 base64 转换。
  • 为什么您的解决方案需要更多内存?我无法理解。我们只返回一小部分结果。是因为collect 声明吗?
  • 我的意思是使用 collect 的解决方案,我怀疑它会将收集的节点加载到内存中,如果是这样,该集合将包含所有标记为 Molecule ...
  • 谢谢。也许 Neo4j 在collect 之前对索引语句进行了优化。另外,我认为您的答案应该是答案。前一个只会使复杂性变得更糟。他们只是串行地执行 2 个查询。取而代之的是,他们可以并行执行 2 个查询。
  • 我尝试将此查询与一组相对较大的节点(290 万个节点)一起使用。我使用OPTIONAL MATCH (x:Card) WHERE ( (TRUE) ) RETURN ID(x), x SKIP 0 LIMIT 10 之类的查询在这 290 万张卡片中获取了 10 张卡片。它在 1 或 2 毫秒内执行。当我尝试OPTIONAL MATCH (x:Card) WHERE ( (TRUE) ) RETURN collect(ID(x))[0..10], collect(x)[0..10], length(collect(x)) 时,它首先在 4500 毫秒内执行。在第二次运行中,它在 2700 毫秒内执行。它看起来还不错,但肯定更慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多