#mongodb #aggregation-framework
#mongodb #aggregation-framework
Вопрос:
У меня много документов, хранящихся в коллекции mongodb (> 1 МЛН). У каждого документа есть временная метка, и они разделены на множество категорий (символов). Как я могу получить самый последний документ (по временной метке) в каждой категории? Имейте в виду, что этот запрос должен быть максимально эффективным из-за большого количества документов.
Мой первоначальный подход состоял в том, чтобы отсортировать всю коллекцию, а затем каким-то образом выбрать документы с помощью distinct
. После некоторого чтения руководства по mongodb я понял, что запрос на агрегацию лучше всего соответствует моим потребностям. Это то, что у меня есть прямо сейчас:
db.trades.aggregate([{$group: {_id: '$symbol', time: {$max: '$time'}}}])
Это не кажется правильным также, правильный ли это подход к тому, что я пытаюсь сделать?
Комментарии:
1. Можете ли вы предоставить несколько примеров для документов.
Ответ №1:
Вы можете использовать оператор $first. Что — то вроде
db.trades.aggregate([
{$sort: {time: -1}},
{$group: {_id: '$symbol', doc: {$first: '$$ROOT'}}}
])
Вам необходимо создать индекс для обеспечения наилучшей производительности:
db.trades.createIndex( { time: -1 } )
Комментарии:
1. Не будет ли это сортировать всю коллекцию каждый раз? Неужели нет способа обойти это?
2. $sort — это первый этап, поэтому он может извлечь выгоду из индекса. Я обновил ответ.
3. Это у меня уже есть. Я подумал, может быть, группировка перед сортировкой или что-то в этомроде. Ваше решение работает, но это занимает ~ 4 секунды даже с индексом.
4. Я думаю, тогда вам нужен составной индекс.
db.trades.createIndex({symbol: 1, time: -1})
5. Индексы могут использоваться только на первом этапе и только для сортировки или сопоставления docs.mongodb.com/master/core/aggregation-pipeline /…