¿Cómo se consulta "no es nulo" en Mongo?

Respuestas:

813

Esto devolverá todos los documentos con una clave llamada "URL DE IMAGEN", pero aún pueden tener un valor nulo.

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

Esto devolverá todos los documentos con una clave llamada "URL de IMAGEN" y un valor no nulo.

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

Además, según los documentos, $ existe actualmente no puede usar un índice, pero $ ne sí.

Editar: Agregar algunos ejemplos debido al interés en esta respuesta

Dados estos insertos:

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

Esto devolverá los tres documentos:

db.test.find();

Esto devolverá solo el primer y el segundo documento:

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

Esto devolverá solo el primer documento:

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

Esto devolverá solo el segundo y tercer documento:

db.test.find({"check":null})
Tim Gautier
fuente
13
Según los documentos, $ne incluye documentos que no contienen el campo . ¿Ha cambiado esto desde que publicaste la respuesta? docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao
2
No creo que eso haya cambiado. Al marcar $ ne, el valor se verifica en todos los documentos, incluidos los que no contienen el campo, pero $ ne: nulo aún no coincidirá con un documento que no contenga el campo ya que el valor del campo sigue siendo nulo, a pesar de que el campo no existe en ese documento.
Tim Gautier
2
¿Cómo se compara el segundo documento?
BT
1
@River Lo comprobé cuando escribí esto hace 3 años y, para asegurarme, acabo de instalar Mongo y lo probé nuevamente. Todavía funciona de la misma manera, la respuesta es correcta. La segunda a la última consulta devuelve solo el primer documento.
Tim Gautier el
1
Los ejemplos dados hacen que sea realmente comprensible cómo usar esto. :-)
Eric Dela Cruz
92

Un trazador de líneas es el mejor:

db.mycollection.find({ 'fieldname' : { $exists: true, $ne: null } });

Aquí,

mycollection : coloca el nombre de tu colección deseada

nombre del campo : colocar el nombre del campo deseado

Explicación:

$ existe : cuando es verdadero, $ existe coincide con los documentos que contienen el campo, incluidos los documentos donde el valor del campo es nulo. Si es falso, la consulta solo devuelve los documentos que no contienen el campo.

$ ne selecciona los documentos donde el valor del campo no es igual al valor especificado. Esto incluye documentos que no contienen el campo.

Entonces, en su caso proporcionado, la consulta siguiente devolverá todos los documentos con el campo imageurl y no tiene un valor nulo:

db.mycollection.find({ 'imageurl' : { $exists: true, $ne: null } });
Amitesh
fuente
11
$exists: trueEs redundante, $ne: nulles suficiente.
Stanislav Karakhanov
Esta debería ser la mejor respuesta. $exists: truedevuelve nullvalores también. Tiene que haber ambos $exists: truey $ne: null. NO es redundante.
Ismail Kattakath
47

En pymongo puedes usar:

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

Porque pymongo representa a mongo "nulo" como python "Ninguno".

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

buscar documentos que contienen este nombre_archivo incluso si es nulo.

Mi propuesta:

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

Puede verificar el tipo de atributo requerido, devolverá todos los documentos que su field_name consultado contiene un valor porque está verificando el tipo del archivo, de lo contrario, si es nulo, la condición de tipo no coincide, por lo que no se devolverá nada.

Nota : si field_name tiene una cadena vacía que significa "", se devolverá. Es el mismo comportamiento para

db.collection_name.find({"filed_name":{$ne:null}});

Validación adicional:

Bien, así que aún no hemos terminado, necesitamos una condición adicional.

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

O

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

Referencia

Farouk El kholy
fuente
14

Compartir para futuros lectores.

Esta consulta funcionó para nosotros (consulta ejecutada desde la brújula MongoDB ):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}
Mohammed Zameer
fuente
1
{$ existe: verdadero, $ ne: nulo} no mostró el resultado correcto. Su consulta funciona bien
Oleksandr Buchek
1
Tenga cuidado, $ nin a menudo no se optimiza sobre los índices
Wheezil
4
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})
Berhanu Tarekegn
fuente
¿Es este un documento Json válido? Dos propiedades con el mismo nombre en el documento de consulta. No estoy seguro de cómo construiría eso en la memoria si fuera necesario.
BrentR
4

En un caso ideal, le gustaría probar los tres valores , nulo , "" o vacío (el campo no existe en el registro)

Puedes hacer lo siguiente.

db.users.find({$and: [{"name" : {$nin: ["", null]}}, {"name" : {$exists: true}}]})
Ankit Marothi
fuente
3

Una alternativa que no se ha mencionado, pero que puede ser una opción más eficiente para algunos (no funcionará con entradas NULL) es usar un índice disperso (las entradas en el índice solo existen cuando hay algo en el campo). Aquí hay un conjunto de datos de muestra:

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 }

Ahora, cree el índice disperso en el campo imageUrl:

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

Ahora, siempre existe la posibilidad (y en particular con un pequeño conjunto de datos como mi muestra) de que, en lugar de usar un índice, MongoDB use un escaneo de tabla, incluso para una posible consulta de índice cubierta. Resulta que eso me da una manera fácil de ilustrar la diferencia aquí:

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" }
{  }
{  }

OK, entonces los documentos adicionales sin no imageUrlse devuelven, solo están vacíos, no es lo que queríamos. Solo para confirmar por qué, explique:

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
}

Entonces, sí, a BasicCursores igual a un escaneo de tabla, no usó el índice. Forcemos la consulta para usar nuestro índice disperso con un 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" }

Y está el resultado que estábamos buscando: solo se devuelven los documentos con el campo poblado. Esto también solo usa el índice (es decir, es una consulta de índice cubierta), por lo que solo el índice debe estar en la memoria para devolver los resultados.

Este es un caso de uso especializado y no se puede usar en general (ver otras respuestas para esas opciones). En particular, debe tenerse en cuenta que, tal como están las cosas, no puede usar count()de esta manera (para mi ejemplo, devolverá 6, no 4), por lo que solo debe usar cuando sea apropiado.

Adam Comerford
fuente
los campos de texto siempre son índices dispersos, no tiene que especificarlo explícitamente. solo mis 2 centavos.
alianos-
3

La forma más simple de verificar la existencia de la columna en mongo compass es:

{ 'column_name': { $exists: true } }
Taha Hamedani
fuente
1
El problema con esto es que asume que el campo realmente nunca persistió, pero el OP parece indicar (desde el título) que podría existir, pero se establece en nulo explícitamente.
Carighan
-10

la consulta será

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

devolverá todos los documentos que tengan "URL DE IMAGEN" como clave ...........

Sagar Varpe
fuente
1
@kilianc Eso no es cierto. $ exist también capturará valores nulos. Ver docs.mongodb.org/manual/reference/operator/query/exists
dorvak
@dorvak exactamente, por eso eso no satisfará el caso de uso en la pregunta.
kilianc
Esta respuesta es incorrecta debido a $existslos controles de la llave "IMAGE URL"y no tiene en cuenta que el valor de ( null) y se volverá un documento con "IMAGE URL" : null.
David Hariri