计算关系类型的数量,以将它们作为频率属性添加到边缘

时间:2019-06-17 16:27:30

标签: neo4j cypher

我正在尝试在neo4j图中计算不同类型的关系,以将它们作为“频率”属性添加到相应的边(即,我有4种e:EX关系类型,所以我希望类型的边EX的e.frequency = 4)。

到目前为止,我已经使用了以下代码:

MATCH ()-[e:EX]-()
WITH e, count(e) as amount  
SET e.frequency = amount
RETURN e

对于这段代码,我对所有EX边返回的e.frequency是2。也许这里有人知道如何纠正这个问题?

2 个答案:

答案 0 :(得分:1)

听起来像您希望此信息以后可以快速访问该类型的任何节点。如果您打算删除或添加图形中的边,您应该意识到数据将很快变得过时,而在整个图形范围内进行查询以更新图形中每个边的属性都没有道理。

感谢Neo4j保留了各种统计信息的事务计数存储,包括每种关系类型的关系数。

最简单的方法是通过Neo4j本身或APOC过程中的过程调用来获取这些信息。

如果已安装APOC,则可以看到如下的关系类型计数图:

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

如果知道要计数的类型,则可以在relTypesCount映射中使用点符号来获取有问题的值。

如果它是动态的(要么作为参数传入,要么在与查询中的关系匹配后获得),则可以使用map索引表示法来获取有问题的计数,如下所示:

CALL apoc.meta.stats() YIELD relTypesCount
MATCH ()-[r]->()
WITH relTypesCount, r
LIMIT 5
RETURN type(r) as type, relTypesCount[type(r)] as count

如果您没有APOC,则可以使用db.stats.retrieve('GRAPH COUNTS') YIELD data,但是您必须做一些额外的过滤以确保获得给定类型的所有关系的计数,以及排除包含开始或结束节点标签的计数:

CALL db.stats.retrieve('GRAPH COUNTS') YIELD data
WITH [entry IN data.relationships WHERE NOT exists(entry.startLabel) AND NOT exists(entry.endLabel)] as relCounts
MATCH ()-[r]->()
WITH relCounts, r
LIMIT 5
RETURN type(r) as type, [rel in relCounts WHERE rel.relationshipType = type(r) | rel.count][0] as count

答案 1 :(得分:1)

首先,这是查询的作用

// Match all EX edges (relationships), ignore direction
MATCH ()-[e:EX]-()
// Logical partition; With the edges, count how many times that instance occurred (will always be 2. (a)-[e:EX]->(b) and the reverse order of (b)<-[e:EX]-(a)
WITH e, count(e) as amount
// Set the property frequency on the instance of e to amount (2)
SET e.frequency = amount
// return the edges
RETURN e

因此,要过滤重复项(反向匹配),您需要在MATCH上指定方向。 MATCH ()-[e:EX]->()这样。对于频率部分,您甚至不需要匹配;您可以只计算模式WITH SIZE(()-[:EX]->()) as c的出现次数(大小,因为模式匹配会返回一个列表,而不是行集)

所以

WITH SIZE(()-[:EX]->()) as c
MATCH ()-[e:EX]->()
SET e.frequency = c
return e

尽管,一旦创建或删除EX边缘,频率就会失效,所以我只需要询问边缘计数就可以打开Cypher。

此外,在这种情况下,获取关系计数的最佳方法是使用MATCH-COUNT,因为这种形式可以帮助Cypher刨床识别出它可以从其内部元数据存储中获取边缘计数。

MATCH ()-[e:EX]->()
WITH COUNT(e) as c
MATCH ()-[e:EX]->()
SET e.frequency = c
return e