首页 > 解决方案 > 通过参数对相同标签的节点进行分组

问题描述

我是图形数据库的新手,如果我弄错了一些正确的术语,我深表歉意。

我正在使用 Neo4j 并且有一个由 - 主要是 - 一种节点组成的数据集。这些节点具有各种参数以及彼此之间以及图中其他标记节点之间的关系。

举一个我想要实现的简单示例,假设我有一个“Person”标签。每个人都有一个名为“性别”的参数,其值为“男性”或“女性”。如果我想运行一个查询,该查询将在一个变量中返回所有男性,而在另一个变量中返回所有女性,那么最佳做法是什么?它们应该是单独的标签吗?考虑到每个参数都是相同的,这似乎是个坏主意。

标签: neo4jcypher

解决方案


由于 neo4j 数据库维护标签计数统计,使用MaleFemale标签将立即获得这些计数——甚至不需要进行任何节点查询。

例如,此查询Male从统计信息中获取节点数:

MATCH (:Male)
RETURN COUNT(*) AS males

但是,当前的 Cypher 规划器似乎拒绝在同一查询中第二次使用统计信息(基于我的PROFILE运行),因此以下查询实际上将扫描数据库中的Female节点。希望这可以在未来的 Cypher 规划器中得到改进。

MATCH (m:Male)
WITH COUNT(m) AS males
MATCH (f:Female)
RETURN males, COUNT(f) AS females

[更新 1]

但是,正如@InverseFalcon 所建议的那样, usingUNION ALL确实会导致每次都使用统计信息:

MATCH (m:Male) RETURN {male: COUNT(m)} AS counts
UNION ALL
MATCH (f:Female) RETURN {female: COUNT(f)} AS counts

[更新 2]

如果您想获得实际节点而不是计数,那么有 2 个答案具有大致相同的性能(如他们PROFILE的 s 所示)。

  1. 您可以使用MaleFemale标签:

    MATCH (m:Male)
    WITH COLLECT(m) AS males
    MATCH (f:Female)
    RETURN males, COLLECT(f) AS females
    
  2. 您可以在以下位置创建索引:Person(gender)

    MATCH (m:Person {gender: 'male'})
    WITH COLLECT(m) AS males
    MATCH (f:Person {gender: 'female'})
    RETURN males, COLLECT(f) AS females
    

    但是,这种方法需要更多的存储空间,因为您必须在每个节点中存储性别属性。


推荐阅读