Я недавно начал набрасывать личный проект, в котором будет задействована социальная сеть.У меня есть некоторый профессиональный опыт работы с Neo4j, и хотя мне кажется, что это идеальное совпадение, есть один вопрос, который меня интересует.
Представьте себе общую социальную сеть: пользователи следуют друг за другом, пользователи публикуют сообщения, пользователи могут видеть написанные сообщенияпользователями они следуют.Это четко выражено в узлах с пометкой Neo4j через :User
и :Post
, связанных через отношения :posted
и :follows
.
Таким образом, я мог получать сообщения пользователей, которым я следую, используя запрос типа:
MATCH (:User {user_id: 1})-[:follows]->(:User)-[:posted]->(p:Post)
RETURN p
Это довольно чисто и просто.Я обеспокоен тем, что реально я захочу получить последние 10 постов, а затем 10 постов и так далее.
Итак, я создал индекс для поля created_at
в узлах :Post
и добавил в запрос предложение ORDER BY p.created_at DESC
.Я подумал, что это позволит мне эффективно сортировать их, однако выполнение EXPLAIN
для этого запроса показывает, что предложения ORDER BY
по большей части не используют индексы для ускорения этого процесса.Поэтому я не уверен, есть ли способ получить их эффективно, когда результирующий набор становится значительно большим.
Это может быть неопытностью или неправильным подходом к этой модели данных.Могу ли я получить какую-то информацию по этой проблеме?Должен ли я моделировать свои данные по-другому?Мой запрос / индекс неверен?Я что-то упускаю?Как бы вы это сделали?
РЕДАКТИРОВАТЬ 1: Пример запроса для чего-то вроде того, что я имел в виду:
MATCH (:User {user_id: 1})-[:follows]->(:User)-[:posted]->(p:Post)
RETURN p
ORDER BY p.created_at DESC
LIMIT 10
Также я думал, что используя диапазон (в предложении WHERE
) есть возможность ограничить размер набора результатов, но все еще не уверены, есть ли лучший способ?
РЕДАКТИРОВАТЬ 2 (Решение): Это был последний запрос, которыйзаставил планировщика Cypher использовать индекс для этой проблемы:
MATCH (:User {user_id: 1})-[:follows]->(:User)-[:posted]->(p:Post)
USING INDEX p:Post(created_at)
WHERE p.created_at < datetime()
RETURN p
ORDER BY p.created_at DESC
LIMIT 10