Я изо всех сил найти решение проблемы с Монго DB:MongoDB - Сортировка по вычисляемое поле
мне нужно выполнить запрос на коллекции с высокой записи/чтения соотношение. Запрос состоит в сортировке документов по полю, которое получено из других полей , принадлежащих одному и тому же документу. Кроме того, одно из этих полей - это размер массива, что делает его еще сложнее.
Простой пример:
D1 - { _id: 1, field: 1, array_field: [a,b,c,d] } -> score = 1 + 4 = 5
D2 - { _id: 2, field: 2, array_field: [a,b] } -> score = 2 + 2 = 4
Ожидаемый результат:
D1 - { _id: 2, score: 4 }
D2 - { _id: 1, score: 5 }
(Счет не требуется в результирующем)
Растворы я пытался до сих пор:
A dd оценка как поле документа, которое постоянно обновляется, другие поля обновляются. Проблемы:
- Это не представляется возможным параметризацию запроса (настройки) после того, как счет был вычисленного
- Это дорого, так как индекс на счете должен быть обновлен очень часто
Создайте конвейер агрегации, который упрощает разработку и решает проблему параметризации. Тем не менее, падение производительности на самом деле очень велико. Mongo не может полагаться на индексы использования вычисляемых полей, вызывая проблемы с памятью (ошибка запроса 100 МБ). Возможное решение - включить флаг
allowDiskUse
. Однако запрос будет слишком медленным.
Update: я хотел бы указать на то, что запрос будет работать около 10 раз в секунду. Поэтому предварительное вычисление и хранение оценки в другом документе может оказаться нецелесообразным решением.
Pratical Use: так как проблема очень сложная. Позвольте мне дать вам немного больше контекста. У меня есть документ с сообщениями (например, сообщения facebook). Я сортирую данные по дате создания и последнему обновлению. Я хотел бы иметь возможность сортировать сообщения по «горячей», что определяется оценкой, о которой я говорил. Я думал, что интересный способ вычислить счет может быть следующим:
score = a * likes - b * dislikes + c * num_comments + d * (now - creation_date)
где a
, b
, c
и d
являются параметры можно изменить для настройки алгоритма. likes
и dislikes
- это массивы ObjectID
s, ссылающиеся на пользователей, а num_comments
- это просто количество комментариев. Запрос выполняется для предоставления ответа конечной точке REST. Дальнейшие операции: Запрос -> Запрос -> Ответ.
Имеете ли вы опыт работы с производными/агрегированными полями? Спасибо!
Когда я столкнулся с подобной проблемой некоторое время назад, я закончил тем, что задерживал отчет. Я создал новую коллекцию с агрегацией и $ out, у которой не было других записей, поэтому я мог использовать индексы для ее оптимизации. Я не уверен, что это было оптимальное решение, но это сработало для меня. – Tiramisu