【问题标题】:Query to search for any user showing first those who are "friends" and "friends of friends" of specific user查询任何用户,首先显示特定用户的“朋友”和“朋友的朋友”
【发布时间】:2015-09-06 23:49:13
【问题描述】:

我是 neo4j 和 Cypher 的新手。

目前我正在开发一个使用 neo4j 获取数据的社交网站。这将在顶部栏中有一个搜索选项,用于查找社交网络上的其他用户,但对于结果,我想首先显示那些是朋友的人,然后是朋友的朋友的人,然后是其他人。所有这些,分页搜索结果就像在 facebook 中搜索一样。

为了实现这一点,我正在寻找使用 Cypher 为该搜索选项创建最佳查询的方法。

我的 USER 节点的结构如下:

(me:User { mid:"1234", name:"John Doe", email:"juan.arango1234@gmail.com" })

其中“mid”属性是自定义 ID。

USER节点之间的友谊关系在两个方向都有标签“FRIENDOF”:

(a:User)-[:FRIENDOF]->(b:User) and (a:User)<-[:FRIENDOF]-(b:User)

为此我设计的最有效的查询是:

MATCH p = allShortestPaths((me:User)-[:FRIENDOF*]->(other:User))
WHERE me.mid = "1234"
AND other.name = "Any user name"
RETURN other, length(p) AS Length
ORDER BY length(p) ASC
SKIP 10
LIMIT 10

这个查询似乎运行良好,但我无法理解应该有一个更优化的方法来处理这个查询。

按照 Neo4j 文档 (http://neo4j.com/docs/stable/cypher-cookbook-friend-finding.html) 的示例,我尝试通过将朋友、朋友的朋友和其他人的查询与 UNION 操作混合来创建此查询,但由于实际情况,使用 UNION 我无法分页结果issue 1879 (https://github.com/neo4j/neo4j/issues/1879) 和相关的2725,“others”的查询需要之前查询的结果(朋友和朋友的朋友)

有什么更好的想法可以让这个查询在 Neo4j 方面的成本更低?

如何搜索不是朋友或朋友的朋友的用户?

谢谢!

【问题讨论】:

    标签: neo4j cypher social-networking


    【解决方案1】:

    您有一个很好的查询起点。您只需要考虑 shortestPath 应该是可选的(因此用户未连接),因此,考虑到这一点,您可以执行以下查询:

    MATCH (me:User {mid:"1234"}), (other:User {name:"Any User name"})
    OPTIONAL MATCH p=shortestPath((me)-[:FRIEND*1..2]-(other))
    RETURN me.mid, other.mid, length(p) as distance
    ORDER BY distance DESC
    

    如果两个用户之间没有路径,则距离将为null,因此您可以在应用程序级别进行检查。

    提示:shortestPath 的默认深度限制为 15。

    参考演示图:http://console.neo4j.org/r/t2n1qc

    编辑

    此查询基于演示控制台,用于检索共同朋友的数量:

    MATCH (me:User { login:'randall.tremblay' })
    MATCH (search:User { login:'witting.franz' })
    OPTIONAL MATCH p=shortestPath((me)-[:FRIEND*]-(search))
    WITH me, search, p, size((me)-[:FRIEND]-()-[:FRIEND]-(search)) AS common
    RETURN me.login, search.login, length(p) AS distance, common
    

    【讨论】:

    • 感谢克里斯托夫!您的建议非常有帮助,因为可选的最短路径仅在 1 到 2 之间跳转,这是我唯一需要为朋友和朋友的朋友订购优先级的东西。
    • 其实我已经添加了一些对朋友建议可以帮助更多的东西:共同朋友的数量......这样可以吗? 'MATCH (me:User {mid:"1234"}), (other:User {name:"Any User name"}) 可选匹配 p=shortestPath((me)-[:FRIENDOF*1..2]-( other)) 可选匹配 c=((me)-[:FRIENDOF]->(common:User)-[:FRIENDOF]->(other)) RETURN other, length(p) as distance, count(common) as FriendsInCommon按距离排序 ASC'
    • 上次查询对 Christophe 很有帮助,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2011-08-10
    • 2013-02-10
    相关资源
    最近更新 更多