Neo4j在链接在一起的节点上对相同属性执行平均操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Neo4j在链接在一起的节点上对相同属性执行平均操作相关的知识,希望对你有一定的参考价值。

我有一个Neo4j数据库遵循这种形式的模型:

主题的一个中心节点。所有当前医疗数据都以当前关系作为单独节点加入其中。如果特定节点包含医学测试分数,并且该主题已经进行了该测试,之后它将加入具有先前关系的分数。

e.g:

(subject)<-[:Current]-(current_medical_score)<-[:Previous*]<-(previous_medical_score)

我想要做的是计算这个医学测试的平均值,并返回平均值小于确定的截止点的所有主题ID。但是,我的请求似乎只考虑current_medical_score节点执行平均操作时的值。

MATCH (subject)<-[:Current|:Previous*]-(scores)
WHERE scores.MISD IS NOT NULL AND scores.MISD <> 999
WITH scores, avg(scores.MISD) as sumMis
WHERE sumMis < 4
RETURN scores.SID, sumMis;

+---------------------+
| scores.SID | sumMis |
+---------------------+
| "330"      | 2.0    |
| "2445"     | 2.0    |
+---------------------+

我检查分数MISD是否为空或999,因为一些提供数据的机构利用999来表示缺失数据。对象2445的当前MIS得分为2,一个得分为8,因此预期平均值应为5.0

不是2.0

我无法弄清楚通过可变数量的关系并计算所有相关节点中的值之间的平均值所需的语法。

任何帮助将不胜感激。

答案

考虑此示例数据集:

create (subject:Subject {ID:"2442"})
    <-[:Current]-(:Score {MISD:2.0, SID: "2442"})
    <-[:Previous]-(:Score {MISD:8.0, SID: "2442"})

你的问题是你是通过score变量对结果进行分组。你应该用subject分组。那就是:WITH subject, (...)而不是WITH scores, (...)

MATCH (subject:Subject)<-[:Current|:Previous*]-(scores)
WHERE scores.MISD IS NOT NULL AND scores.MISD <> 999
WITH subject, avg(scores.MISD) as sumMis
RETURN subject.ID, sumMis;

输出:

╒════════════╤════════╕
│"subject.ID"│"sumMis"│
╞════════════╪════════╡
│"2442"      │5       │
└────────────┴────────┘
另一答案

您看到这些结果的原因是:

WITH scores, avg(scores.MISD) as sumMis

聚合函数(如avg())仅对非聚合列具有意义,这些列构成分组键。

在这种情况下,这一行写着:“对于每个单独的分数(因为这里的scores不是分数的集合,它是单个分数,每个记录/行一个分数),找到该单个分数的MISD属性的平均值”。得到的每行平均值只是MISD属性,因为单个值的平均值是相同的值。

因此,该子句的结果实际上是两行,每行一个:Score节点,MISD值为2.0和8.0。然后你的WHERE子句删除值为8的行(因为它> = 2),留下sumMis为2.0。

为了确保avg()函数对所有值执行(而不是获得每个值的平均值:Score节点,这是无用的),您需要在与avg()相同的点汇总所有分数,或者从范围中删除scores那时。

正如布鲁诺的回答一样,当你执行scores时,从范围中移除avg()。但是,如果每个直接连接:Score节点是一个单独的测试类型,如果你有多个:Score节点直接连接到:Subject by:当前关系,那个查询将采用所有这些的平均值,这可能不是什么你要。

理想情况下,您将拥有测试类型的某些属性,这对于:Previous*链中的所有节点都是相同的(但与另一个不同:分数节点直接连接:与主题的当前关系)并且您可以将其用作分组键:

WITH scores.testName as testName, avg(scores.MISD) as sumMis
WHERE sumMis < 4
RETURN subject.ID, testName, sumMis

以上是关于Neo4j在链接在一起的节点上对相同属性执行平均操作的主要内容,如果未能解决你的问题,请参考以下文章

Neo4j 第二篇:图形数据库

neo4j cypher - 匹配不存在相同类型的另一个特定节点的节点

为neo4j中的每个节点设置一个属性

尝试在Neo4J C#Client上使用相同的命令进行展开和合并

Neo4j - 将节点标题设置为 Web 界面中的标签

Neo4j 不对称关系