Возвращает самый последний документ в группе

#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 /…