Производительность агрегирует MongoDB по совпадению и образцу - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть коллекция с 7 миллионами записей.Мне нужно выбрать X случайных элементов между определенным диапазоном дат.

Это моя схема

mongoose.Schema({
        transactionId: {type: String, required: [true, 'transactionId is required'], index: true},
        createdAt: {type: Date, required: [true, 'date is required'], index: true},
        userId: {type: String, required: [true, 'userId is required']}
    });

Это запрос, который я делаю

TransactionModel.aggregate([
        {
            $match: {
                createdAt: {$gte: startDate, $lt: endDate}
            }
        },
        {
            $sample: {
                size: 100,
            }
        }
    ]

И этиВот мои результаты:

Took 458ms to select 100 winners in date range: 1-5-2018 - 1-6-2018
Took 1524ms to select 100 winners in date range: 1-5-2018 - 1-9-2018
Took 2052ms to select 100 winners in date range: 1-4-2018 - 1-4-2019
Took 19249ms to select 100 winners in date range: 1-1-2018 - 1-1-2033

19 секунд кажутся относительно длинными, когда я удаляю $ match из функции агрегирования, мне нужно всего 142 мсек, чтобы выбрать 100 победителей из 7 миллионов записей.

ЕстьЕсть ли способ улучшить скорость с помощью предложения о совпадении?

1 Ответ

0 голосов
/ 16 сентября 2018

Как уже писал Энтони Винзлет, вам нужен индекс по полю созданного. Это может быть либо индекс одного поля, либо составной индекс, где созданный элемент является первой частью.

В дополнение к этому, вам следует предусмотреть этап $ project в случае, если не все поля документа необходимы.

В идеале у вас есть составной индекс, который покрывает ваш запрос.

Вы можете использовать объяснение (), чтобы увидеть, что происходит:

collection.find(
  {createdAt: {$gte: startDate, $lt: endDate}}, 
  { created: 1, otherField: 1 }
).explain('executionStats')
...