Может ли MongoDB использовать индекс при проверке существования поля с оператором $ существующие? - PullRequest
13 голосов
/ 18 ноября 2011

Если у меня есть данные в моей коллекции users, которые выглядят следующим образом:

{ name: '...', 
  email: '...', 
  ...,
  photos: {
     123: { url: '...', title: '...', ... },
     456: { url: '...', title: '...', ... },
     ...
  }
} 

И я хочу выяснить, у какого пользователя есть идентификатор фотографии 127, тогда я использую запрос:

db.users.find( {'photos.127': {'$exists' => true} } );

Я пытался, но не представляется возможным заставить MongoDB использовать индекс для этого запроса. Индекс, который я пробовал, был: db.users.ensureIndex({photos:1});. И когда я использовал explain() mongo сказал мне, что использует BasicCursor (то есть индекс не использовался).

Можно ли создать индекс, который Монго будет использовать для этого запроса?

Ответы [ 3 ]

11 голосов
/ 18 ноября 2011

Нет, нет способа указать mongodb использовать индекс для запроса существующего. Индексирование полностью связано с данными . * * * * * * * * * * * * * * * * * * * * * * * относится только к ключам (полям) *1004*, поэтому его нельзя использовать в индексах.

.

$ exist просто проверяет, существует ли данный ключ (или поле) в документе.

5 голосов
/ 03 декабря 2013

Поскольку запросы MongoDB 2.0 $exists должны использовать индекс.К сожалению, это исправление исчезло в последней версии и будет исправлено в MongoDB 2.5

5 голосов
/ 31 января 2013

$ Существующий не будет использовать индекс, но вы можете изменить структуру данных на

photos: [
     {id:123, url: '...', title: '...', ... },
     {id:456, url: '...', title: '...', ... },
     ...
  ]

, а затем использовать

db.users.ensureIndex({photos.id:1}) 

для создания индекса для идентификатора фотографии.

Кажется, я ошибаюсь, на самом деле, вы можете заставить ваш запрос $ существующие использовать ваш индекс.Давайте продолжим использовать вышеупомянутую структуру, но ваш идентификатор фотографии не обязательно содержится, то есть некоторые документы будут иметь ключ 'id', а некоторые - нет.Затем вы можете создать разреженный индекс для него:

db.users.ensureIndex({'photos.id': 1}, {'sparse': true})

, а затем выполнить запрос следующим образом:

db.users.find({'photos.id': {$exists: true}}).hint({'photos.id': 1})

, который вы можете добавить объяснение, чтобы увидеть, использует ли запрос индекс.Вот мой результат, мобильный ключ моей коллекции похож на ваш photos.id:

> db.test.count()
50000
> db.test.find({'mobile': {$exists: true}}).hint({'mobile': 1}).explain()
{
        "cursor" : "BtreeCursor mobile_1",
        "nscanned" : 49999,
        "nscannedObjects" : 49999,
        "n" : 49999,
        "millis" : 138,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "mobile" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ]
        }
}

> db.test.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "test.test",
                "name" : "_id_"
        },
        {
                "v" : 1,
                "key" : {
                        "mobile" : 1
                },
                "ns" : "test.test",
                "name" : "mobile_1",
                "sparse" : true,
                "background" : true
        }
]

Надеюсь на помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...