Оператор $ 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 })
Это позволит эффективно использовать индекс. Стоит или нет, это будет зависеть от вашего использования данных и вашей модели, конечно