可选节点聚合

Optional node aggregation

在图形数据库中,如何计算用户直接或间接对节点 "comment" 贡献的次数。在下图中,答案是 2(1 个直接,1 个间接)

根据您的示例图,在 Neo4j 中,您可以使用以下 Cypher 查询来捕获直接 (User)-->(Comment) 关系和使用 variable length path operator 的间接 (User)-->(Comment)-->(Comment) 关系:

MATCH (u:User)-[*]->(:Comment)
RETURN u, COUNT(*) AS num

编辑

正如 Bruno 指出的那样,此查询将为您的示例 return 3,因为它考虑了按用户分组的评论的所有路径。相反,您可能对连接到每个用户的 distinct 个评论节点的数量感兴趣:

MATCH (u:User)-[*]->(c:Comment) RETURN u, COUNT(DISTINCT c) AS num

正如您标记的那样orientdb,这是类似于Cypher with OrientDB 的方法之一。

select count(*) from (match {class:User}-->{class:Comment, as:r} return r)

您甚至可以将深度应用于搜索

select count(*) from (match {class:User}-->{class:Comment, as:r, while: ($depth<3)} return r)

With AQL graph traversal in ArangoDB,顶点集合 nodes 包含 usercomment comment-2 和一个带边的边集合 contrib,你可以这样做:

RETURN COUNT(
    FOR v IN 1..5 INBOUND "nodes/comment" contrib
        FILTER v._key == "user"
        RETURN 1
)

遍历从 comment 节点开始,深度从 1 到 5,沿入站方向跟随 contrib 集合中的所有边。应用过滤器以将遍历限制为以 user.

结尾的路径

它找到的两条路径是comment <-- usercomment <-- comment-2 <-- user。对于这两条路径,返回一个常量值(我们实际上不需要任何节点)。周围的RETURN COUNT()语句统计了子查询returns有多少结果,所以2.

也可以反过来遍历,从commentuser:

RETURN COUNT(
    FOR v IN 1..5 OUTBOUND "nodes/user" contrib
        FILTER v._key == "comment"
        RETURN 1
)

在一个大图上,您可以测试两个查询并查看一个查询是否比另一个执行得更好。还可以考虑使用 traversal options,如 bfs(广度优先搜索)和 uniqueVertices 进行查询优化。