MongoDb как запрос с производительностью сортировки - PullRequest
0 голосов
/ 18 февраля 2019

Я использую mongodb 3.6, в которой у меня есть коллекция Usermst, в которой есть документы пользователей.Я собираюсь получить имя и фамилию пользователя, который сделал больше сообщений.Ниже мой запрос mongodb.

    db.getCollection("UserMst").aggregate([
    {$match :{$and:[{os : {$in:[0,1]}}, {_id : {$nin : [3,10]}}]}}
    ,{$match:{$and:
         [ {$or: [
           {$and : [{fname:{$regex : `^has.*` , $options: 'i' }},{lname:{$regex : `^pa.*` , $options: 'i' }}]}  
          ,{$and:  [{fname:{$regex : `^pa.*` , $options: 'i' }}, {lname:{$regex : `^has.*` , $options: 'i' }}]}
          ]}
         ]
         }
    }
    ,{$sort:{'posts':-1,'_id':-1}}
    ,{$project:{"fname":1,"lname":1,"posts":1}}
    ,{$limit:5}
    ])

У меня есть индекс "name": "os_1_posts_-1".Этот запрос занимает много времени. Есть ли способ оптимизировать запрос?

1 Ответ

0 голосов
/ 18 февраля 2019
  1. Если вы посмотрите на свое совпадение: {$match :{$and:[{os : {$in:[0,1]}}, {_id : {$nin : [3,10]}}]}} вы увидите, что вы пытаетесь сопоставить на os и _id - если вы пытаетесь сопоставить на _id, вы 'Вам часто захочется, чтобы в вашем индексе было _id.
  2. В следующем $ match вы пытаетесь найти совпадение для fname ИЛИ lname - это медленно, если не проиндексировано (иИЛИ в целом трудно индексировать).Похоже, что это может быть часть запроса с наибольшим количеством элементов.
  3. На самом деле вы не используете какие-либо специфические функции агрегации в этом конвейере!Вместо этого вы можете написать это как обычный запрос и использовать проекцию и ограничение.Вы также используете $and в тех местах, где вам это не нужно

Ваш запрос конвейера агрегации выглядит примерно так:

{
  os: {$in: [0, 1] },
  _id : {$nin : [3,10]},
  $or: [
    {
      fname: { $regex: `^has.*` , $options: 'i' },
      lname:{ $regex: `^pa.*` , $options: 'i' }
    },
    {
      fname: {$regex : `^pa.*` , $options: 'i' },
      lname:{$regex : `^has.*` , $options: 'i' 
    }
  ]
}

А затем сортируется по postsа затем _id

Я не уверен, какие поля имеют наивысшую мощность, как выглядят ваши данные и какие другие запросы вы выполняете в этой базе данных, поэтому очень трудно рекомендовать фактический индекс, но составной индекс, который выглядит как {lname, fname, os, posts, _id}, должен работать лучше.

...