【问题标题】:Optimising neo4j cypher query for retrieving a social news feed优化 neo4j 密码查询以检索社交新闻提要
【发布时间】:2015-10-15 06:53:19
【问题描述】:

到目前为止,我已经尝试过此查询,但扫描所有节点时速度确实很慢。它能够实现我想要检索的内容

match (u:Users{user_id:140}),(p:Posts),(pu:Users{user_id:p.created_by}) optional match  (p)-[:POST_MEDIA]->(f) optional match (p)-[:COMMENT]->(c)<-[:COMMENT]-(u3)
where
(p)-[:CREATED_BY]->(u) or (p:PUBLIC and (u)-[:FOLLOW]->(pu) )or  (p:PRIVATE and (p)-[:SHARED_WITH]->(u))
return {user_id:pu.user_id,firstname:pu.firstname,lastname:pu.lastname,profile_photo:pu.profile_photo,username:pu.username} as pu,p,collect({user_id:u3.user_id,profile_photo:u3.profile_photo,text:c.text}) as comment,collect(f) as file order by p.post_id DESC  limit 25

在此查询之前,我尝试了此查询,该查询速度非常快,但无法检索完整的新闻提要正在检索新闻源。

    match (u:Users{user_id:140})-[:FOLLOW]->(pu)<-[:CREATED_BY]-(p:Posts)
    optional match  (p)-[:POST_MEDIA]->(f)
    optional match (p)-[:COMMENT]->(c)<-[:COMMENT]-(u3) where p:PUBLIC     
    return
    {user_id:pu.user_id,firstname:pu.firstname,
   lastname:pu.lastname,profile_photo:pu.profile_photo,username:pu.username} as pu,p,
   collect({user_id:u3.user_id,profile_photo:u3.profile_photo,text:c.text}) as comment,
   collect(f) as file order by p.post_id DESC  limit 25

注意:- 在 where 子句中不要像这样修改:-

where p:PUBLIC or (p)-[:SHARED_WITH]->(u)
// but the only problem is that how i should include posts of users himself which is retrieving news feed .

【问题讨论】:

    标签: php neo4j cypher feed


    【解决方案1】:

    首先,您应该确保在user_id 属性上具有User 标签的索引。像这样:

    CREATE INDEX ON :Users(user_id)
    

    (顺便说一句,标签使用单数名词是常见的做法)

    但您也应该使用 Neo4j 关系,而不是从帖子的 created_by 列进行匹配。与检查索引(仍然很快,但我认为不太理想)相比,这将允许 Neo4j 遍历关系(非常快)

    但我认为你也有一个问题,WHERE 中的变量应该直接放在有问题的(OPTIONAL) MATCH 之后的WHERE 子句中。例如,您的(p)-[:CREATED_BY]-&gt;(u) 条件是指在第一个MATCH 中定义的变量,但它们低于OPTIONAL MATCH,并且WHERE 实际上适用于OPTIONAL MATCH。您应该可以通过在两者之间添加 WITH * 来解决此问题,但您希望对性能进行基准测试。

    以下是其中一些更改的查询(不是您需要先单独设置CREATED 关系):

    MATCH
      (u:Users {user_id:140}),
      (p:Posts)<-[:CREATED]-(pu:Users)
    WHERE
      (p)-[:CREATED_BY]->(u) OR
      (p:PUBLIC AND (u)-[:FOLLOW]->(pu)) OR
      (p:PRIVATE AND (p)-[:SHARED_WITH]->(u))
    OPTIONAL MATCH (p)-[:POST_MEDIA]->(f)
    OPTIONAL MATCH (p)-[:COMMENT]->(c)<-[:COMMENT]-(u3)
    RETURN
      {user_id:pu.user_id,
        firstname:pu.firstname,
        lastname:pu.lastname,
        profile_photo:pu.profile_photo,
        username:pu.username} as pu,
      p,
      collect({user_id:u3.user_id,
               profile_photo:u3.profile_photo,
               text:c.text}) as comment,
      collect(f) as file
    ORDER BY p.post_id DESC LIMIT 25
    

    编辑:实际上,看看这个,WHERE 中的所有变量都在第一个MATCH 中定义,所以你应该可以把它移到那里。编辑查询以反映这一点。

    EDIT2:您可以尝试使用OPTIONAL MATCH,我认为这会让 Neo4j 先进行遍历。使用WHERE,我认为它会获取所有可能的结果,然后进行过滤,这不会那么有效。

    PROFILE 
    MATCH
      (u:Users {user_id:140}),
      (p:Posts)<-[:CREATED]-(pu:Users)
    OPTIONAL MATCH (p)-[created_by:CREATED_BY]->(u), (u)-[follow:FOLLOW]->(pu), (p)-[shared_with:SHARED_WITH]->(u)
    WHERE created_by IS NOT NULL OR (p:PUBLIC AND follow IS NOT NULL) OR (p:PRIVATE AND shared_with IS NOT NULL)
    OPTIONAL MATCH (p)-[:POST_MEDIA]->(f)
    OPTIONAL MATCH (p)-[:COMMENT]->(c)<-[:COMMENT]-(u3)
    RETURN
      {user_id:pu.user_id,
        firstname:pu.firstname,
        lastname:pu.lastname,
        profile_photo:pu.profile_photo,
        username:pu.username} as pu,
      p,
      collect({user_id:u3.user_id,
               profile_photo:u3.profile_photo,
               text:c.text}) as comment,
      collect(f) as file
    ORDER BY p.post_id DESC LIMIT 25
    

    您可能还想尝试使用索引属性来指示private,而不是使用标签。

    【讨论】:

    • 如果您仍然遇到问题,请尝试分享查询的PROFILE
    • 是的,我已经为 user_id、post_id 和其他 id 相关字段建立了索引
    • 好的,对 sql 有很好的体验,这就是为什么我达到了这么高的 cql 水平,但实际上我只有 10 天的 neo4j 经验,你的意思是“查询所花费的时间”由 PROFILE 跨度>
    • 但是兄弟,你的代码 sn-p 将扫描所有节点......比我创建的关系的用途是什么:SHARED_WITH 你能建议我一种方法,以便我在匹配中直接使用 shared_with 关系,以便它提供了超快的结果并分别检索公共帖子 btw +1
    • 如果你在查询前加上PROFILE ,它将输出有关 Neo4j 如何执行你的查询以及慢点在哪里的信息。 neo4j.com/docs/stable/how-do-i-profile-a-query.html
    【解决方案2】:

    你应该使用 Match(c) 匹配 (p:Posts) 我的意思是使用多个匹配。 此外,您应该对用户 user_id 使用约束。

    你不应该在 where 子句中使用 ()-[]->()。也许你可以使用可选的 Match。

    您还应该分析您的查询以查看其行为方式。所以你可以减少你的数据库命中。

    【讨论】:

    • 你能详细说明你在说什么吗请给一个简短的sn-p
    • 在很多情况下,您都希望在 WHERE 子句中指定模式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多