2015-10-15 80 views
1

到目前为止,我已经尝试过这个查询,但它扫描所有节点的速度非常慢。它能够是我想要检索优化neo4j密码查询以检索社交新闻Feed

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 . 

回答

0

你应该使用匹配(三)比赛(P:帖子),我的意思是使用多个比赛。 另外你应该对用户user_id使用约束。

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

您还应该剖析您的查询以了解其行为。所以你可以减少你的db命中。

+0

你会说出你在说什么吗?请给出一个简短的片段 –

+0

有很多情况下你想在WHERE子句中指定一个模式。 –

2

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

CREATE INDEX ON :Users(user_id) 

(顺便说一下它的使用单数名词的标签常见的做法)

但你也应该用Neo4j的关系,而不是从这篇文章的created_by列匹配。这将允许Neo4j遍历关系(这是非常快的)相比,检查指数(这仍然是快速的,但并不理想,我认为)

但你也有一个问题,我认为,与事实那么WHERE中的变量应该在(OPTIONAL) MATCH之后直接放在WHERE子句中。例如,您的(p)-[:CREATED_BY]->(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,而不是使用标签。

+0

如果仍然有问题,请尝试共享查询的“PROFILE” –

+0

是的,我已经在user_id,post_id和其他id相关的字段上建立了索引 –

+0

确实对sql有很好的体验,这就是为什么我达到了这么高的水平的cql,但实际上我只有10天neo4j的经验,并且你的意思是'查询时间'由PROFILE –