it-swarm-eu.dev

Wie fragt man in Mongo nach "is not null"?

Ich möchte eine folgende Abfrage ausführen:

db.mycollection.find(HAS IMAGE URL)

Was sollte die richtige Syntax sein?

328
TIMEX

Dadurch werden alle Dokumente mit einem Schlüssel namens "IMAGE URL" zurückgegeben, die jedoch möglicherweise noch einen Nullwert haben.

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

Dies gibt alle Dokumente mit einem Schlüssel namens "IMAGE URL" und einem Wert ungleich Null zurück.

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

Außerdem kann $ exists laut Dokumentation derzeit keinen Index verwenden, $ ne jedoch.

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

Angesichts dieser Einsätze:

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

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

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})
701
Tim Gautier

Ein Liner ist der beste:

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

Hier,

mycollection: Geben Sie den gewünschten Sammlungsnamen ein

Feldname: Geben Sie den gewünschten Feldnamen ein

Erklärung:

$ exists: Wenn true, stimmt $ exists mit den Dokumenten überein, die das Feld enthalten, einschließlich der Dokumente, 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 dem von Ihnen angegebenen Fall ist folgende Abfrage vorhanden, die alle Dokumente mit dem Feld imageurl zurückgibt und keinen Nullwert hat:

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

In Pymongo können Sie verwenden:

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

Weil pymongo mongo "null" als python "None" darstellt.

42
user2293072

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

abrufen von Dokumenten, die diesen Feldnamen 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 Felds überprüfen. Wenn er null ist, stimmt die Typbedingung nicht überein, sodass nichts zurückgegeben wird.

N.b : Wenn der Feldname eine leere Zeichenfolge hat, die "" bedeutet, wird diese 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 und brauchen eine zusätzliche Bedingung.

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

OR

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

Referenz für alle Typen: https://docs.mongodb.com/manual/reference/operator/query/type/#op._S_type

14
Farouk El kholy

Teilen für zukünftige Leser.

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

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

Eine Alternative, die nicht erwähnt wurde, die für einige jedoch effizienter sein kann (sie funktionieren nicht mit NULL-Einträgen), ist die Verwendung eines sparse index (Einträge im Index sind nur vorhanden, wenn sie vorhanden sind etwas auf dem Gebiet). 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 jetzt den Sparse-Index für das imageUrl-Feld:

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

Nun gibt es immer die Möglichkeit (und insbesondere bei einem kleinen Datensatz wie meinem Beispiel), dass MongoDB anstelle eines Indexes einen Tabellenscan verwendet, auch für eine mögliche verdeckte 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, also werden die zusätzlichen Dokumente ohne imageUrl zurückgegeben, nur leer, nicht das, was wir wollten. Nur um zu bestätigen, warum, erklären Sie:

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, ein BasicCursor entspricht einem Tabellenscan, er hat den Index nicht verwendet. Lassen Sie uns die Abfrage zwingen, unseren Sparse-Index mit einem hint() zu verwenden:

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 es gibt das Ergebnis, nach dem wir gesucht haben - es werden nur Dokumente mit dem ausgefüllten Feld zurückgegeben. Dies verwendet auch nur den Index (d. H. Es handelt sich um eine verdeckte Indexabfrage), sodass nur der Index im Speicher sein 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 ist zu beachten, dass Sie count() aus heutiger Sicht nicht auf diese Weise verwenden können (in meinem Beispiel wird 6 und nicht 4 zurückgegeben). Verwenden Sie diese Option daher nur, wenn dies angemessen ist.

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