【发布时间】:2017-08-15 20:11:02
【问题描述】:
【问题讨论】:
-
图中的边/关系类型是什么?
标签: neo4j cypher orientdb arangodb
【问题讨论】:
标签: neo4j cypher orientdb arangodb
根据您的示例图,在 Neo4j 中,您可以使用以下 Cypher 查询来捕获直接 (User)-->(Comment) 关系和使用 variable length path operator 的间接 (User)-->(Comment)-->(Comment):
MATCH (u:User)-[*]->(:Comment)
RETURN u, COUNT(*) AS num
编辑
正如 Bruno 指出的那样,此查询将为您的示例返回 3,因为它考虑到按用户分组的 cmets 的所有路径。相反,您可能对连接到每个用户的不同评论节点的数量感兴趣:
MATCH (u:User)-[*]->(c:Comment)
RETURN u, COUNT(DISTINCT c) AS num
【讨论】:
MATCH (u:User)-[*]->(:Comment {text:'comment'}) RETURN u, COUNT(*) AS num 或引用评论的任何其他标识符指定应考虑的评论。
在ArangoDB 中使用AQL graph traversal,一个顶点集合nodes 包含user、comment 和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 <-- user 和comment <-- comment-2 <-- user。对于这两个路径,返回一个常量值(我们实际上不需要任何节点)。周围的RETURN COUNT() 语句计算子查询返回多少个结果,所以2。
你也可以反过来遍历,从comment到user:
RETURN COUNT(
FOR v IN 1..5 OUTBOUND "nodes/user" contrib
FILTER v._key == "comment"
RETURN 1
)
在大图上,您可以测试两个查询,看看其中一个是否比另一个执行得更好。还可以考虑使用traversal options 之类的bfs(广度优先搜索)和uniqueVertices 进行查询优化。
【讨论】:
正如您已标记 orientdb,这是与使用 OrientDB 的 Cypher 类似的方法之一。
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)
【讨论】: