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

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

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.


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



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

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

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.


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

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.