Wie fragt man in Mongo nach "ist nicht null"?

Antworten:

812

Dadurch werden alle Dokumente mit einem Schlüssel namens "IMAGE URL" zurückgegeben, sie können jedoch weiterhin einen Nullwert haben.

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

Dadurch werden alle Dokumente mit einem Schlüssel namens "IMAGE URL" und einem Wert ungleich Null zurückgegeben.

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

Laut den Dokumenten kann $ derzeit keinen Index verwenden, $ ne jedoch.

Bearbeiten: Hinzufügen einiger Beispiele aufgrund des Interesses an dieser Antwort

Angesichts dieser Beilagen:

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

Dadurch werden alle drei Dokumente zurückgegeben:

db.test.find();

Dadurch werden nur das erste und das zweite Dokument zurückgegeben:

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

Dies gibt nur das erste Dokument zurück:

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

Dies gibt nur das zweite und dritte Dokument zurück:

db.test.find({"check":null})
Tim Gautier
quelle
13
$ne Enthält laut Dokumenten Dokumente, die das Feld nicht enthalten . Hat sich dies geändert, seit Sie die Antwort gepostet haben? docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao
2
Ich glaube nicht, dass sich das geändert hat. Bei der Überprüfung von $ ne wird der Wert in allen Dokumenten überprüft, einschließlich derjenigen, die das Feld nicht enthalten. $ Ne: null stimmt jedoch immer noch nicht mit einem Dokument überein, das das Feld nicht enthält, da der Wert des Felds immer noch null ist. obwohl das Feld in diesem Dokument nicht vorhanden ist.
Tim Gautier
2
Wie passt man gerade zum zweiten Dokument?
BT
1
@ River Ich habe es überprüft, als ich es vor 3 Jahren geschrieben habe, und um sicher zu gehen, habe ich gerade Mongo installiert und es erneut ausprobiert. Es funktioniert immer noch genauso, die Antwort ist richtig. Die vorletzte Abfrage gibt nur das erste Dokument zurück.
Tim Gautier
1
Die Beispiele machen es wirklich verständlich, wie man das benutzt. :-)
Eric Dela Cruz
92

Ein Liner ist der beste:

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

Hier,

mycollection : Geben Sie Ihren gewünschten Sammlungsnamen ein

Feldname : Geben Sie Ihren gewünschten Feldnamen ein

Erklärung:

$ existiert : Wenn true, stimmt $ exist mit den Dokumenten überein, die das Feld enthalten, einschließlich Dokumenten, bei denen der Feldwert null ist. Wenn false, gibt die Abfrage nur die Dokumente zurück, die das Feld nicht enthalten.

$ ne wählt die Dokumente aus, bei denen der Wert des Feldes nicht dem angegebenen Wert entspricht. Dies schließt Dokumente ein, die das Feld nicht enthalten.

In Ihrem angegebenen Fall ist die folgende Abfrage vorhanden, bei der alle Dokumente mit dem Bild imageurl zurückgegeben werden und die keinen Nullwert haben:

db.mycollection.find({ 'imageurl' : { $exists: true, $ne: null } });
Amitesh
quelle
11
$exists: trueist redundant, $ne: nullist genug.
Stanislav Karakhanov
Dies sollte die beste Antwort sein. $exists: truegibt auch nullWerte zurück. Es muss beides geben $exists: trueund $ne: null. Es ist NICHT redundant.
Ismail Kattakath
47

In Pymongo können Sie verwenden:

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

Weil Pymongo Mongo "null" als Python "None" darstellt.

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

Rufen Sie Dokumente ab, die diesen Dateinamen enthalten, auch wenn er null ist.

Mein Vorschlag:

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

Sie können den Typ des erforderlichen Attributs überprüfen. Es werden alle Dokumente zurückgegeben, deren abgefragter Feldname einen Wert enthält, da Sie den Typ des Dateis überprüfen. Andernfalls stimmt die Typbedingung nicht überein, sodass nichts zurückgegeben wird.

Nb : Wenn der Feldname eine leere Zeichenfolge hat, die "" bedeutet, wird sie zurückgegeben. Dies ist das gleiche Verhalten für

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

Zusätzliche Validierung:

Okay, wir sind noch nicht fertig, wir brauchen eine zusätzliche Bedingung.

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

ODER

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

Referenz

Farouk El Kholy
quelle
14

Teilen für zukünftige Leser.

Diese Abfrage hat bei uns funktioniert (Abfrage vom MongoDB-Kompass ausgeführt ):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}
Mohammed Zameer
quelle
1
{$ existiert: wahr, $ ne: null} zeigte kein korrektes Ergebnis. Ihre Anfrage funktioniert gut
Oleksandr Buchek
1
Seien Sie vorsichtig, $ nin optimiert oft nicht über Indizes
Wheezil
4
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})
Berhanu Tarekegn
quelle
Ist dies ein gültiges Json-Dokument? Zwei gleichnamige Eigenschaften im Abfragedokument. Ich bin mir nicht sicher, wie Sie das im Speicher aufbauen würden, wenn Sie müssten.
BrentR
4

Im Idealfall möchten Sie alle drei Werte testen , null , "" oder leer (Feld im Datensatz nicht vorhanden)

Sie können Folgendes tun.

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

Eine Alternative, die nicht erwähnt wurde, aber für einige eine effizientere Option sein kann (funktioniert nicht mit NULL-Einträgen), ist die Verwendung eines spärlichen Index (Einträge im Index sind nur vorhanden, wenn sich etwas im Feld befindet). Hier ist ein Beispieldatensatz:

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 }

Erstellen Sie nun den Sparse-Index für das Feld imageUrl:

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

Jetzt besteht immer die Möglichkeit (und insbesondere bei einem kleinen Datensatz wie meinem Beispiel), dass MongoDB anstelle eines Index einen Tabellenscan verwendet, selbst für eine potenziell abgedeckte Indexabfrage. Wie sich herausstellt, kann ich den Unterschied hier auf einfache Weise veranschaulichen:

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, die zusätzlichen Dokumente ohne Nein imageUrlwerden zurückgegeben, nur leer, nicht das, was wir wollten. Um zu bestätigen, warum, erklären Sie Folgendes:

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
}

Also, ja, a BasicCursorentspricht einem Tabellenscan, es wurde der Index nicht verwendet. Lassen Sie uns die Abfrage zwingen, unseren Sparse-Index mit einem zu verwenden 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" }

Und da ist das Ergebnis, nach dem wir gesucht haben - nur Dokumente mit dem ausgefüllten Feld werden zurückgegeben. Dies verwendet auch nur den Index (dh es handelt sich um eine abgedeckte Indexabfrage), sodass sich nur der Index im Speicher befinden muss, um die Ergebnisse zurückzugeben.

Dies ist ein spezieller Anwendungsfall und kann nicht allgemein verwendet werden (siehe andere Antworten für diese Optionen). Insbesondere sollte beachtet werden, dass Sie dies aus heutiger Sicht nicht count()auf diese Weise verwenden können (in meinem Beispiel wird 6 statt 4 zurückgegeben). Verwenden Sie es daher bitte nur, wenn dies angemessen ist.

Adam Comerford
quelle
Textfelder sind immer spärliche Indizes, das müssen Sie nicht explizit angeben. nur meine 2 Cent.
Alianos
3

Der einfachste Weg, um die Existenz der Säule im Mongo-Kompass zu überprüfen, ist:

{ 'column_name': { $exists: true } }
Taha Hamedani
quelle
1
Das Problem dabei ist, dass davon ausgegangen wird, dass das Feld wirklich nie beibehalten wurde, aber das OP scheint (aus der Überschrift) anzuzeigen, dass es existieren könnte, aber explizit auf Null gesetzt werden kann.
Carighan
-10

Die Abfrage wird sein

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

Es werden alle Dokumente zurückgegeben, deren Schlüssel "IMAGE URL" ist.

Sagar Varpe
quelle
1
@ Kilianc Das stimmt nicht. $ existiert erfasst auch Nullwerte. Siehe docs.mongodb.org/manual/reference/operator/query/exists
dorvak
@dorvak genau, deshalb wird das den Anwendungsfall in der Frage nicht befriedigen.
Kilianc
Diese Antwort ist falsch, da $existsnach dem Schlüssel gesucht wird "IMAGE URL"und sein Wert ( null) nicht berücksichtigt wird und ein Dokument mit zurückgegeben wird "IMAGE URL" : null.
David Hariri