В MongoDB вы можете индексировать поле, чтобы найти объекты, которые не имеют значения в массиве? - PullRequest
1 голос
/ 22 февраля 2012

Я знаю, что Multikeys позволяет эффективно находить объекты, которые имеют массив в виде поля, где в этом массиве присутствует определенное значение.

Например, вы можете сохранитьobject:

{
  "ar":["book","cat"]
}

И затем, при условии, что поле "ar" проиндексировано, вы можете сказать:

db.blah.find({"ar":"cat"})

И он эффективно найдет вышеуказанный объект.

Однако, что-то вроде этой работы:

db.blah.find({"ar":{$not : "cat"}})

Здесь я бы хотел найти все объекты, где массив "ar" не содержит "cat".Будет ли этот запрос работать, и если он работает, будет ли он эффективным?(т.е. будет ли он использовать индекс в поле "ar"?)

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Оператор $ not используется не в том виде, в каком вы подразумеваете, это мета-оператор, который используется для отмены проверки только другого оператора. Я думаю, что вы на самом деле хотите использовать $ ne:

db.blah.find({ "ar" : { $ne : "cat"}})

Если вы сделаете это, и у вас будет индекс «ar», то, поскольку это отрицательное совпадение, вам придется сканировать практически все документы в индексе, чтобы проверить каждый из них - это на самом деле менее эффективно, чем сканировать таблицу в одиночку, потому что вам нужно выполнить индексную загрузку / сканирование, а затем вытащить все данные, чтобы получить результаты тоже.

Если это достаточно важно и достаточно часто, чтобы избежать этого, то почему бы не добавить простое поле true / false (или 0/1 в моем примере) для проверки существования поля «cat» , Здесь, я добавляю такое поле к существующему набору данных, я бы предложил добавить его при создании или модификации, чтобы добавить «cat» в будущем - обычно хорошей идеей является избегание пакетных операций:

db.blah.update({ "ar" : "cat"}, { $set : {"cat_test" : 1 } }, true, true)
db.blah.update({ "ar" : {$ne : "cat"}}, { $set : {"cat_test" : 0 } }, true, true)
db.blah.ensureIndex({ "cat_test" : 1 })

Теперь вы можете просто запустить что-то вроде:

db.blah.find({ "cat_test" : 0 })

Это позволит эффективно использовать индекс. Стоит или нет, это будет зависеть от вашего использования данных и вашей модели, конечно

1 голос
/ 22 февраля 2012

Если вы посмотрите на эту проблему с сервером MongoDB , ответ будет «он может использовать индекс».

Однако при использовании оператора $not это часто неочень эффективно использовать индекс.Если в 2% записей отображается 'cat', вам все равно придется прочитать 98% данных.В этот момент вы можете просто прочитать весь набор данных по одной записи за раз.

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