Как вы запрашиваете «не является нулевым» в Монго?

201
db.mycollection.find(HAS IMAGE URL)
Теги:
database
nosql

5 ответов

497

Это приведет к возврату всех документов с помощью клавиши "URL-адрес IMAGE", но они все равно могут иметь нулевое значение.

db.mycollection.find({"IMAGE URL":{$exists:true}});

Это приведет к возврату всех документов с помощью ключа, называемого "URL-адрес IMAGE", и ненулевого значения.

db.mycollection.find({"IMAGE URL":{$ne:null}});

Кроме того, согласно документам, $exists в настоящее время не может использовать индекс, но $ne может.

Изменить: добавление некоторых примеров из-за интереса к этому ответу

Учитывая эти вставки:

db.test.insert({"num":1, "check":"check value"});
db.test.insert({"num":2, "check":null});
db.test.insert({"num":3});

Это вернет все три документа:

db.test.find();

Это возвращает только первый и второй документы:

db.test.find({"check":{$exists:true}});

Это вернет только первый документ:

db.test.find({"check":{$ne:null}});

Это возвращает только второй и третий документы:

db.test.find({"check":null})
  • 6
    Это правильный ответ!
  • 11
    Согласно документам, $ne включает документы, которые не содержат поля . Изменилось ли это с тех пор, как вы опубликовали ответ? docs.mongodb.org/manual/reference/operator/query/ne
Показать ещё 9 комментариев
29

В pymongo вы можете использовать:

db.mycollection.find({"IMAGE URL":{"$ne":None}});

Поскольку pymongo представляет mongo "null" как питон "None".

4

db.collection_name.find({"filed_name":{$exists:true}});

извлекать документы, содержащие это filed_name, даже если оно равно null.

Мое предложение:

db.collection_name.find({"field_name":{$type:2}}) //type:2 == String

Вы можете проверить требуемый тип атрибута, он вернет все документы, в которые запрашивается его имя_файла, содержит значение, потому что вы проверяете тип filed else, если он равен null, условие типа не соответствует, и ничего не будет возвращено.

N.b: если поле_имя имеет пустую строку, что означает "", оно будет возвращено. Это то же поведение для db.collection_name.find({"filed_name":{$ne:null}});

Дополнительная проверка:

Хорошо, поэтому мы еще не закончили, нам нужно дополнительное условие.

db.collection_name. find({ "field_name":{$type:2},$where:"this.field_name.length >0"})

ИЛИ

db.collection_name. find({ "field_name":{$ne:null},$where:"this.field_name.length >0"})

Ссылка для всех типов: https://docs.mongodb.com/manual/reference/operator/query/type/#op._S_type

2

Альтернатива, которая не упоминалась, но может быть более эффективным вариантом для некоторых (не будет работать с записями NULL) заключается в использовании разреженных index (записи в индексе существуют только в том случае, если в поле есть что-то). Вот пример набора данных:

db.foo.find()
{ "_id" : ObjectId("544540b31b5cf91c4893eb94"), "imageUrl" : "http://example.com/foo.jpg" }
{ "_id" : ObjectId("544540ba1b5cf91c4893eb95"), "imageUrl" : "http://example.com/bar.jpg" }
{ "_id" : ObjectId("544540c51b5cf91c4893eb96"), "imageUrl" : "http://example.com/foo.png" }
{ "_id" : ObjectId("544540c91b5cf91c4893eb97"), "imageUrl" : "http://example.com/bar.png" }
{ "_id" : ObjectId("544540ed1b5cf91c4893eb98"), "otherField" : 1 }
{ "_id" : ObjectId("544540f11b5cf91c4893eb99"), "otherField" : 2 }

Теперь создайте разреженный индекс в поле imageUrl:

db.foo.ensureIndex( { "imageUrl": 1 }, { sparse: true } )
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

Теперь всегда есть шанс (и, в частности, с небольшим набором данных, подобным моему примеру), который вместо использования индекса MongoDB будет использовать сканирование таблицы даже для потенциального охваченного индекса. Как оказалось, это дает мне простой способ проиллюстрировать разницу здесь:

db.foo.find({}, {_id : 0, imageUrl : 1})
{ "imageUrl" : "http://example.com/foo.jpg" }
{ "imageUrl" : "http://example.com/bar.jpg" }
{ "imageUrl" : "http://example.com/foo.png" }
{ "imageUrl" : "http://example.com/bar.png" }
{  }
{  }

ОК, поэтому дополнительные документы без imageUrl возвращаются, просто пусты, а не то, что мы хотели. Чтобы подтвердить, почему, объясните:

db.foo.find({}, {_id : 0, imageUrl : 1}).explain()
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 6,
    "nscannedObjects" : 6,
    "nscanned" : 6,
    "nscannedObjectsAllPlans" : 6,
    "nscannedAllPlans" : 6,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "server" : "localhost:31100",
    "filterSet" : false
}

Итак, да, a BasicCursor равно сканированию таблицы, он не использовал индекс. Позвольте заставить запрос использовать наш разреженный индекс с помощью hint():

db.foo.find({}, {_id : 0, imageUrl : 1}).hint({imageUrl : 1})
{ "imageUrl" : "http://example.com/bar.jpg" }
{ "imageUrl" : "http://example.com/bar.png" }
{ "imageUrl" : "http://example.com/foo.jpg" }
{ "imageUrl" : "http://example.com/foo.png" }

И есть результат, который мы искали - возвращаются только документы с заполненным полем. Это также использует только индекс (т.е. Это закрытый индексный запрос), поэтому только индекс должен быть в памяти для возврата результатов.

Это специализированный вариант использования и не может использоваться в целом (см. другие ответы для этих опций). В частности, следует отметить, что, поскольку вы стоите, вы не можете использовать count() таким образом (для моего примера он вернет 6 не 4), поэтому, пожалуйста, используйте только, когда это необходимо.

  • 0
    текстовые поля всегда разреженные индексы, вам не нужно указывать это явно. только мои 2 цента.
-3

Запрос будет

db.mycollection.find({"IMAGE URL":{"$exists":"true"}})

он вернет все документы, имеющие "URL-адрес IMAGE" в качестве ключа...........

  • 8
    это не работает, если doc ['IMAGE URL'] = null
  • 0
    @kilianc Это не правда. $ Существуют также и нулевые значения. См. Docs.mongodb.org/manual/reference/operator/query/exists.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню