到目前为止,我已尝试过此查询,但扫描所有节点时速度非常慢。它能够我想要检索
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 :(得分:2)
首先,您应该确保user_id
标签的User
属性上有索引。像这样:
CREATE INDEX ON :Users(user_id)
(顺便说一句,通常使用单数名词作为标签)
但你也应该使用Neo4j关系,而不是匹配帖子的created_by
列。与检查索引相比,这将允许Neo4j遍历关系(这是非常快的)(我认为这仍然很快,但不是那么理想)
但我认为,你也有一个问题,即WHERE
中的变量应该直接放在WHERE
子句后面(OPTIONAL) MATCH
。例如,您的(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
,而不是使用标签。
答案 1 :(得分:0)
你应该使用Match(c)match(p:Posts)我的意思是使用多个匹配。 您还应该在User user_id上使用约束。
你不应该在where子句中使用() - [] - &gt;()。也许你可以使用可选的匹配。
您还应该对查询进行概要分析,以了解其行为方式。所以你可以减少db命中率。