Neo4j知识库(二):使用计数存储快速统计

【翻译自:https://neo4j.com/developer/kb/fast-counts-using-the-count-store/
【由Neo4j APAC授权编译发布

Neo4j知识库

        Neo4j维护计数存储文件,用于保存许多对象的统计元数据。
        计数存储用于通知查询计划器,让它能够在查询规划时做出明智的选择。
        从计数存储获取统计数据的时间固定,您从计数存储获得某个对象的统计信息非常快速。
        通过 EXPLAIN 查询,我们可以从查询计划中判断查询是否使用了计数存储,若使用则可看到 NodeCountFromCountStore 或 RelationshipCountFromCountStore 操作符。

1、计数存储查询的限制

        根据定义,使用计数查询必须存在 count() 聚合。
        WHERE 条件句不能使用,匹配模式中也不能有任何属性。
        由于查询计划器的限制,count() 仅在 WITH 或 RETURN 上单独进行聚合时,才会使用计数存储。

       【限制–如果count()聚合范围内还有其它变量,则不会使用计数存储。】

        如前所述,通过查看查询计划中是否存在 NodeCountFromCountStore 或  RelationshipCountFromCountStore,来判断计数存储是否被使用。
        文末我们将讨论在同一查询中返回多个计数时的解决方法。

2、节点统计

        您可以使用计数存储来获取数据库中所有节点的计数:

MATCH (n)
RETURN count(n) as count

        您还可以获取某一标签所有节点的计数:

MATCH (n:Person)
RETURN count(n) as count

        这些查询中变量可选,您可以忽略它们,使用count(*)可得到相同结果:

MATCH ()
RETURN count(*) as count

        和

MATCH (:Person)
RETURN count(*) as count

        【限制–无法使用计数存储来查询多个标签的节点。】

        查询多标签节点将不使用计数存储,因为这些数据未在计数存储中保存。
        下面的查询将使用计数存储:

MATCH (n:Person:Director)
RETURN count(n) as count

3、关系计数

        计数存储还保存关系的计数元数据,所用模式必须描述单一关系。注意,查询在匹配模式中 必须 使用有向关系 才能 使用计数存储,请不要忽略方向。
        无论是否存在关系类型,都将使用计数存储:

MATCH ()-[r]->()
RETURN count(r) as count
MATCH ()-[r:ACTED_IN]->()
RETURN count(r) as count

        查询多种类型的关系时,计数存储依然会被使用,对每种类型的关系计数进行累加:

MATCH ()-[r:ACTED_IN|DIRECTED]->()
RETURN count(r) as count

        与节点一样,变量可选,count(*)可以代替使用:

MATCH ()-[:ACTED_IN]->()
RETURN count(*) as count

4、TO/FROM单个标签节点的关系计数

        计数存储也保存了每一标签为结束节点的关系计数。以下查询将从计数存储中获取其统计数据。

MATCH ()-[r:ACTED_IN]->(:Movie)
RETURN count(r) as count

MATCH (:Person)-[r:ACTED_IN]->()
RETURN count(r) as count

MATCH ()-[r]->(:Movie)
RETURN count(r) as count

        【限制–开始节点和结束节点的标签都存在时不能使用计数存储。】

        计数存储不保存开始节点和结束节点同时存在标签的元数据。
        下面的查询将使用计数存储:

MATCH (:Person)-[r:ACTED_IN]->(:Movie)
RETURN count(r) as count

5、单个查询获取多个计数

    如果您想在单个查询中从计数存储获取多个计数,则可能会遇到前文提到的限制:必须在 WITH 或 RETURN 子句中单独使用 count() 聚合。

5.1 计数查询使用UNION ALL

        如果我们对不同查询使用计数存储来获得计数,UNION 合并,很方便即可获得所需的计数:

MATCH (n:Person)
WITH count(n) as count
RETURN 'Person' as label, count
UNION ALL
MATCH (n:Movie)
WITH count(n) as count
RETURN 'Movie' as label, count

        注意,如果我们需要另一变量来提供上下文,该变量只能在获得 count() 后才能引入,因为聚合处的其它变量会阻止使用计数存储。
        另外,我们可以返回 map 结构数据,包括标签类型及其相关计数:

MATCH (n:Person)
RETURN {label:'Person', count: count(n)} as info
UNION ALL
MATCH (n:Movie)
RETURN {label:'Movie', count: count(n)} as info

5.2 使用apoc.cypher.run()动态获取每个标签/类型的计数

        apoc.cypher.run() 用于每次执行一个 Cypher 查询,可以让您从每次的计数存储中获取计数。
        通过调用节点标签或关系类型,可以高效便捷的同时获取多个计数:
        对于标签:

CALL db.labels() YIELD label
CALL apoc.cypher.run('MATCH (:`'+label+'`) RETURN count(*) as count',{}) YIELD value
RETURN label, value.count

        对于关系:

CALL db.relationshipTypes() YIELD relationshipType as type
CALL apoc.cypher.run('MATCH ()-[:`'+type+'`]->() RETURN count(*) as count',{}) YIELD value
RETURN type, value.count

5.3 使用APOC过程apoc.meta.stats()

        APOC Procedures 有 meta procedures,可用于访问几乎所有计数存储数据。
        您可以通过 CALL apoc.meta.stats() ,选择要显示的数据。

5.3.1 内容

        调用 apoc.meta.stats() 将返回以下值:

labelCount – 图中标签数
relTypeCount – 图中关系类型数
propertyKeyCount – 图中属性键数量
nodeCount – 图中节点数
relCount – 图中关系数
Labels – 每种标签的映射及该标签的计数
relTypes – 每种关系模式的映射,包含关系类型、每种标签作为结束节点的模式及相关的计数
relTypesCount – 每种关系类型的映射及该类型的计数
stats –包含上述所有计数的映射

5.3.2 用法

        labels 计数通常最有用,类似方法可以用于其它:

CALL apoc.meta.stats() YIELD labels
RETURN labels

        返回如下映射:

{
"Movie": 38,
"Word": 12,
"News": 2,
"Director": 28,
"Reviewer": 3,
"Person": 133,
"Sentence": 17
}

        获取其中一个值,就像使用“.”获取键值一样容易。

CALL apoc.meta.stats() YIELD labels
RETURN labels.Person as personCount

        如果需要多个值,我们可以使用以下查询:

CALL apoc.meta.stats() YIELD labels
RETURN labels {.Person, .Movie, .Director} as counts

更多技术咨询: 
yusonglin@we-yun.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • neo4j使用使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大。 和SQL很相...
    8a590e918db0阅读 4,223评论 0 0
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,435评论 0 13
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,712评论 0 8
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,718评论 2 9
  • 游戏先于努力;而且,鼓励至关重要。尤其在刚开始做一件事的时候,孩子们更需要鼓励和自由,才能弄清楚自己真正的兴趣是什...
    莉莉俺的路西阅读 168评论 0 0