簡體   English   中英

優化neo4j密碼查詢以檢索社交新聞提要

[英]Optimising neo4j cypher query for retrieving a social news 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 .

首先,您應確保在user_id屬性上有一個用於User標簽的索引。 像這樣:

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屬性,而不是使用標簽。

您應該使用Match(c)match(p:Posts)我的意思是使用多個匹配項。 另外,您應該對用戶user_id使用約束。

您不應在where子句中使用()-[]->()。 也許您可以使用可選的匹配。

您還應該配置查詢以查看其行為。 因此,您可以減少數據庫命中率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM