S
S
Stanislav2018-02-08 23:29:45
MongoDB
Stanislav, 2018-02-08 23:29:45

How to optimize mongodb query?

Hello everyone, can you tell me how to optimize the query below, or maybe even revise the structure of the document. Any information would be helpful.
There are documents of the form, I list only the most important fields

{
    url: 'string',
    public: 'number',
    tags: 'Array(String)',
    catalog: 'ObjectId()'
}

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

The request is stupid when I need to make a selection of similar records sorted by the tags field, in the case when there are few documents with identical tags, the request is relatively fast, but if there are thousands of such documents, then about 1.5-2 seconds are already running. Which is really bad.
Here is the request
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()

Problem field tags, when sorting, if you remove { $sort: { tags: 1 } } the request is executed in 8ms instead of 1.5s.
Indexes
The scheme says
schema.index( { url: 1, public: 1, tags: 1, catalog: 1, tags: 1 } )

In fact, an index url_1_public_1_tags_1_catalog_1 is created, ignoring one more sorting tags
What to do?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
asd111, 2018-02-09
@asd111

See explain-Collection.explain.aggregate.....

P
Philipp, 2018-02-09
@zoonman

Make custom index for tags

schema.index( { url: 1 } )
schema.index( { tags: 1 }, {sparse: true} )
schema.index( { catalog: 1 } )

Glue tags into one field, build an index on it.
RTFM mongoosejs.com/docs/guide.html#indexes
Sorting takes a long time because the index catalog_1_tags_1 is used for the condition. Of course, sorting by it will not work.
Try sorting like this:
{ $sort: { catalog: 1, tags: 1 } },

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question