Neo4j - Получение списка узлов Post в порядке даты публикации - PullRequest
2 голосов
/ 15 марта 2019

Я недавно начал набрасывать личный проект, в котором будет задействована социальная сеть.У меня есть некоторый профессиональный опыт работы с 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

1 Ответ

2 голосов
/ 15 марта 2019

Neo4j 3.5 представил некоторую поддержку для использования индексов для выполнения ORDER BY операций с некоторыми ограничениями.

Но в настоящее время (в neo4j 3.5.3), даже когда использование индекса поддерживается для ORDER BY, планировщик Cypher, похоже, не использует его автоматически для этой цели. В своих экспериментах с версией 3.5.3 я обнаружил, что если вы не используете индекс в предложении WHERE, то планировщик не будет использовать индекс вообще.

Итак, в качестве простого обходного пути, вы можете просто добавить тривиальное предложение WHERE, используя индекс. Например, вот модифицированная версия вашего запроса, которая «обманывает» планировщика, используя индекс для ORDER BY:

MATCH (:User {user_id: 1})-[:follows]->(:User)-[:posted]->(p:Post)
WHERE p.created_at > 0
RETURN p
ORDER BY p.created_at DESC
LIMIT 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...