Come si esegue una query per "non è null" in Mongo?


Risposte:


813

Ciò restituirà tutti i documenti con una chiave denominata "URL IMMAGINE", ma potrebbero comunque avere un valore nullo.

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

Ciò restituirà tutti i documenti con una chiave denominata "URL IMMAGINE" e un valore non nullo.

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

Inoltre, secondo i documenti, $ esiste attualmente non può usare un indice, ma $ ne può.

Modifica: aggiunta di alcuni esempi a causa dell'interesse per questa risposta

Dati questi inserti:

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

Questo restituirà tutti e tre i documenti:

db.test.find();

Ciò restituirà solo il primo e il secondo documento:

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

Questo restituirà solo il primo documento:

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

Ciò restituirà solo il secondo e il terzo documento:

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

13
Secondo i documenti, $ne include documenti che non contengono il campo . È cambiato da quando hai pubblicato la risposta? docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao

2
Non credo che sia cambiato. Quando si seleziona $ ne, il valore viene verificato in tutti i documenti, inclusi quelli che non contengono il campo, ma $ ne: null non corrisponderà ancora a un documento che non contiene il campo poiché il valore del campo è ancora nullo, anche se il campo non esiste in quel documento.
Tim Gautier,

2
Come abbini il secondo documento?
BT,

1
@River Ho controllato quando l'ho scritto 3 anni fa e, per essere sicuro, ho appena installato Mongo e l'ho provato di nuovo. Funziona ancora allo stesso modo, la risposta è corretta. La penultima query restituisce solo il 1o documento.
Tim Gautier,

1
Gli esempi forniti rendono davvero comprensibile come usarlo. :-)
Eric Dela Cruz il

92

Una fodera è la migliore:

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

Qui,

mycollection : inserisci il nome della tua collezione desiderata

fieldname : inserisci il nome del campo desiderato

Spiegazione:

$ esiste : quando è vero, $ esiste corrisponde ai documenti che contengono il campo, inclusi i documenti in cui il valore del campo è nullo. Se è falso, la query restituisce solo i documenti che non contengono il campo.

$ ne seleziona i documenti in cui il valore del campo non è uguale al valore specificato. Ciò include i documenti che non contengono il campo.

Quindi, nel tuo caso fornito, esiste la seguente query che restituisce tutti i documenti con il campo imageurl e che non hanno valore null:

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

11
$exists: trueè ridondante, $ne: nullè abbastanza.
Stanislav Karakhanov,

Questa dovrebbe essere la risposta migliore. $exists: truerestituisce nullanche valori. Devono esserci entrambi $exists: truee $ne: null. NON è ridondante.
Ismail Kattakath,

47

In pymongo puoi usare:

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

Perché pymongo rappresenta mongo "null" come python "None".


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

recupera i documenti che contengono questo nome file anche se è nullo.

La mia proposta:

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

Puoi controllare il tipo di attributo richiesto, restituirà tutti i documenti che il suo field_name interrogato contiene un valore perché stai controllando il tipo di file archiviato altrimenti se è nullo la condizione del tipo non corrisponde quindi non verrà restituito nulla.

Nb : se field_name ha una stringa vuota che significa "", verrà restituito. È lo stesso comportamento per

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

Convalida aggiuntiva:

Ok, quindi non abbiamo ancora finito, abbiamo bisogno di una condizione extra.

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

Riferimento


14

Condivisione per i futuri lettori.

Questa query ha funzionato per noi (query eseguita dalla bussola MongoDB ):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}

1
{$ esiste: vero, $ ne: null} non ha mostrato il risultato corretto. La tua query funziona bene
Oleksandr Buchek

1
Fai

4
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})

È un documento Json valido? Due proprietà con lo stesso nome nel documento della query. Non sono sicuro di come lo costruiresti in memoria se dovessi.
BrentR

4

In un caso ideale, si desidera di prova per tutti e tre i valori , nulla , "" o svuotare (campo non esiste nel record)

Puoi fare quanto segue.

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

3

Un'alternativa che non è stata menzionata, ma che potrebbe essere un'opzione più efficiente per alcuni (non funzionerà con le voci NULL) è quella di utilizzare un indice sparse (le voci nell'indice esistono solo quando c'è qualcosa nel campo). Ecco un set di dati di esempio:

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 }

Ora, crea l'indice sparse sul campo imageUrl:

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

Ora, c'è sempre la possibilità (e in particolare con un piccolo set di dati come il mio esempio) che invece di utilizzare un indice, MongoDB utilizzerà una scansione di tabella, anche per una potenziale query di indice coperta. A quanto pare, questo mi dà un modo semplice per illustrare la differenza qui:

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, quindi i documenti extra con no imageUrlvengono restituiti, semplicemente vuoti, non quello che volevamo. Giusto per confermare il perché, spiega:

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
}

Quindi, sì, a BasicCursorequivale a una scansione della tabella, non ha utilizzato l'indice. Forziamo la query per utilizzare il nostro indice sparse 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" }

E c'è il risultato che stavamo cercando: vengono restituiti solo i documenti con il campo popolato. Questo utilizza anche solo l'indice (ovvero è una query di indice coperta), quindi solo l'indice deve essere in memoria per restituire i risultati.

Questo è un caso d'uso specializzato e non può essere usato in generale (vedi altre risposte per quelle opzioni). In particolare, va notato che allo stato attuale non è possibile utilizzare count()in questo modo (per il mio esempio restituirà 6 non 4), quindi si prega di utilizzare solo quando appropriato.


i campi di testo sono sempre indici sparsi, non è necessario specificarlo esplicitamente. solo i miei 2 centesimi.
alianos-

3

Il modo più semplice per verificare l'esistenza della colonna nella bussola mongo è:

{ 'column_name': { $exists: true } }

1
Il problema è che si presume che il campo non sia mai stato veramente persistente, ma l'OP sembra indicare (dal titolo) che potrebbe esistere ma essere impostato su null in modo esplicito.
Carighan,

-10

la query sarà

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

restituirà tutti i documenti con "URL IMMAGINE" come chiave ...........


1
@kilianc Non è vero. $ esiste acquisirà anche valori null. Vedi docs.mongodb.org/manual/reference/operator/query/exists
dorvak

@dorvak esattamente, ecco perché questo non soddisfa il caso d'uso nella domanda.
Kilianc,

Questa risposta è sbagliata, perché $existsi controlli per la chiave "IMAGE URL"e non considera il suo valore ( null) e sarà restituire un documento con "IMAGE URL" : null.
David Hariri,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.