До сих пор я пробовал этот запрос, но он действительно медленный, так как сканирует все узлы. Он способен на то, что я хочу получить
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
следует положить в 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
вместо использования ярлыков.
Вы должны использовать Match (c) match (p: Posts) Я имею в виду использовать несколько совпадений.
Также вы должны использовать ограничения на User user_id.
Вы не должны использовать () — [] -> () внутри предложений where. Может быть, вы могли бы использовать дополнительный матч.
Вы также должны профилировать свой запрос, чтобы увидеть, как он ведет себя. Таким образом, вы можете уменьшить количество попаданий в БД.