ms-dred
@ms-dred
Вечно что то не то и что то не так...

Как оптимизировать запрос mongodb?

Привет всем, может подскажите как можно оптимизировать запрос ниже или быть может вовсе пересмотреть структуру документа. Любая информация будет полезна.

Есть документы вида, перечисляю только самые важные поля
{
    url: 'string',
    public: 'number',
    tags: 'Array(String)',
    catalog: 'ObjectId()'
}

Вот пример заполненного документа
{
    url: 'url-1',
    public: 1,
    tags: [ 'чай', 'кофе' ], // В большинстве своем содержит от 5 до 12 значений
    catalog: ObjectId('db.catalogs._id')
}


Запрос тупит когда мне нужно сделать выборку похожих записей отсортированных по полю tags, в случае когда документов с идентичными тегами немного, запрос выполняется относительно быстро, но если таких документов тысячи, то уже выполняется порядка 1.5-2сек. Что совсем уж плохо.
Вот сам запрос
return Collection
        .aggregate([
            {
                $match: {
                    url: { $ne: request.params.document },
                    public: { $gte: 2 },
                    tags: { $in: request.items.tagsSlice }, //  request.items.tagsSlice - первые 5 тегов основной записи
                    catalog: request.items.catalog._id
                }
            },
            { $sort: { tags: 1 } },
            { $skip: 0 },
            { $limit: 12 },
            {
                $project: {
                   /****/
                }
                
            }
        ])
        .then()


Проблемное поле tags, при сортировке, если убрать { $sort: { tags: 1 } } запрос выполняется за 8ms вместо 1.5с.
Индексы
В схеме прописано
schema.index( { url: 1, public: 1, tags: 1, catalog: 1, tags: 1 } )

По факту создается индекс url_1_public_1_tags_1_catalog_1, игнорируя еще один tags сортировочный

Что делать?
  • Вопрос задан
  • 1566 просмотров
Пригласить эксперта
Ответы на вопрос 2
@asd111
Посмотрите explain - Collection.explain.aggregate.....
Ответ написан
zoonman
@zoonman
⋆⋆⋆⋆⋆
Сделать индивидуальный индекс для тегов
schema.index( { url: 1 } )
schema.index( { tags: 1 }, {sparse: true} )
schema.index( { catalog: 1 } )


Склеить теги в одно поле, построить по нему индекс.

RTFM mongoosejs.com/docs/guide.html#indexes

Сортировка занимает много времени, т.к. используется индекс catalog_1_tags_1 для условия. Разумеется сортировать по нему не получится.
Попробуйте сортировать так:
{ $sort: { catalog: 1, tags: 1 } },
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы