Suchen Sie nach MongoDB-Datensätzen, bei denen das Array-Feld nicht leer ist

502

Alle meine Aufzeichnungen haben ein Feld namens "Bilder". Dieses Feld ist ein Array von Zeichenfolgen.

Ich möchte jetzt die neuesten 10 Datensätze, bei denen dieses Array NICHT leer ist.

Ich habe herum gegoogelt, aber seltsamerweise habe ich nicht viel darüber gefunden. Ich habe in die Option $ where gelesen, aber ich habe mich gefragt, wie langsam das für native Funktionen ist und ob es eine bessere Lösung gibt.

Und selbst dann funktioniert das nicht:

ME.find({$where: 'this.pictures.length > 0'}).sort('-created').limit(10).execFind()

Gibt nichts zurück. Das Verlassen this.picturesohne das Längenbit funktioniert, aber dann werden natürlich auch leere Datensätze zurückgegeben.

Skerit
quelle

Antworten:

827

Wenn Sie auch Dokumente haben, die den Schlüssel nicht haben, können Sie Folgendes verwenden:

ME.find({ pictures: { $exists: true, $not: {$size: 0} } })

MongoDB verwendet keine Indizes, wenn $ size betroffen ist. Hier ist eine bessere Lösung:

ME.find({ pictures: { $exists: true, $ne: [] } })

Seit der Veröffentlichung von MongoDB 2.6 können Sie mit dem Operator vergleichen, dies kann $gtjedoch zu unerwarteten Ergebnissen führen (eine ausführliche Erklärung finden Sie in dieser Antwort ):

ME.find({ pictures: { $gt: [] } })
Chris '
quelle
6
Für mich ist das der richtige Ansatz, da er sicherstellt, dass das Array existiert und nicht leer ist.
LeandroCR
Wie kann ich die gleiche Funktionalität erreichen mitmongoengine
Rohit Khatri
54
VORSICHTIG, ME.find({ pictures: { $gt: [] } })IST GEFÄHRLICH, auch in neueren MongoDB-Versionen. Wenn Sie einen Index in Ihrem Listenfeld haben und dieser Index während der Abfrage verwendet wird, erhalten Sie unerwartete Ergebnisse. Beispiel: db.doc.find({'nums': { $gt: [] }}).hint({ _id: 1 }).count()Gibt die richtige Nummer zurück, während db.doc.find({'nums': { $gt: [] }}).hint({ nums: 1 }).count()zurückgegeben wird 0.
Wojcikstefan
1
Sehen Sie meine detaillierte Antwort unten, um zu erfahren, warum dies für Sie möglicherweise nicht funktioniert: stackoverflow.com/a/42601244/1579058
wojcikstefan
6
Der Kommentar von @ wojcikstefan muss positiv bewertet werden, um zu verhindern, dass Personen den letzten Vorschlag verwenden, der unter bestimmten Umständen keine übereinstimmenden Dokumente zurückgibt.
Thomas Jung
181

Nach einigem Hin und Her, insbesondere in den Mongodb-Dokumenten, und rätselhaften Zusammenhängen war dies die Antwort:

ME.find({pictures: {$exists: true, $not: {$size: 0}}})
Skerit
quelle
27
Das funktioniert nicht. Ich weiß nicht, ob dies zuvor funktioniert hat, aber dies gibt auch Objekte zurück, die nicht den Schlüssel 'Bilder' haben.
Rdsoze
17
Unglaublich, wie diese Antwort 63 positive Stimmen hat, obwohl das, was @rdsoze gesagt hat, wahr ist - die Abfrage gibt auch Datensätze zurück, die das Feld nicht haben pictures.
Dan Dascalescu
5
Seien Sie vorsichtig, mongoDB verwendet keine Indizes, wenn $ size beteiligt ist . Es wäre besser, {$ ne: []} und möglicherweise {$ ne: null} einzuschließen.
Levente Dobson
17
@rdsoze Die allererste Zeile der Frage lautet "Alle meine Datensätze haben ein Feld namens" Bilder ". Dieses Feld ist ein Array" . Darüber hinaus ist dies ein vollkommen realistisches und allgemeines Szenario. Diese Antwort ist nicht falsch, sie funktioniert für die Frage genau so, wie sie geschrieben wurde, und es ist dumm , sie zu kritisieren oder herabzustimmen, weil sie kein anderes Problem löst .
Mark Amery
1
@Cec In der Dokumentation heißt es lediglich, dass bei Verwendung von $ size in der Abfrage kein Index verwendet wird, um schnellere Ergebnisse zu erzielen. Wenn Sie also einen Index für dieses Feld haben und ihn verwenden möchten, bleiben Sie bei anderen Ansätzen wie {$ ne: []}. Wenn dies für Sie funktioniert, wird Ihr Index verwendet.
Levente Dobson
108

Dies könnte auch für Sie funktionieren:

ME.find({'pictures.0': {$exists: true}});
Tenbatsu
quelle
2
Nett! Auf diese Weise können Sie auch nach einer Mindestgröße suchen. Wissen Sie, ob Arrays immer nacheinander indiziert werden? Würde es jemals einen Fall geben, in dem es pictures.2existiert, pictures.1aber nicht?
Anushr
2
Der $existsOperator ist ein Boolescher Wert, kein Offset. @tenbatsu sollte trueanstelle von verwenden 1.
Ekillaby
2
@anushr Would there ever be a case where pictures.2 exists but pictures.1 does not? Ja, dieser Fall könnte passieren .
Die Bndr
@TheBndr Das kann nur passieren, wenn pictureses sich um ein Unterdokument handelt, nicht um ein Array. zBpictures: {'2': 123}
JohnnyHK
4
Dies ist nett und intuitiv, aber Vorsicht, wenn die Leistung wichtig ist - es wird ein vollständiger Sammlungsscan durchgeführt, selbst wenn Sie einen Index haben pictures.
Wojcikstefan
35

Bei der Abfrage sind Ihnen zwei Dinge wichtig - Genauigkeit und Leistung. In diesem Sinne habe ich in MongoDB v3.0.14 einige verschiedene Ansätze getestet.

TL; DR db.doc.find({ nums: { $gt: -Infinity }})ist die schnellste und zuverlässigste (zumindest in der von mir getesteten MongoDB-Version).

EDIT: Dies funktioniert nicht mehr in MongoDB v3.6! In den Kommentaren unter diesem Beitrag finden Sie eine mögliche Lösung.

Installieren

Ich habe 1k Dokumente ohne Listenfeld, 1k Dokumente mit einer leeren Liste und 5 Dokumente mit einer nicht leeren Liste eingefügt.

for (var i = 0; i < 1000; i++) { db.doc.insert({}); }
for (var i = 0; i < 1000; i++) { db.doc.insert({ nums: [] }); }
for (var i = 0; i < 5; i++) { db.doc.insert({ nums: [1, 2, 3] }); }
db.doc.createIndex({ nums: 1 });

Ich erkenne, dass dies nicht ausreicht, um die Leistung so ernst zu nehmen wie in den folgenden Tests, aber es reicht aus, um die Richtigkeit verschiedener Abfragen und das Verhalten ausgewählter Abfragepläne darzustellen.

Tests

db.doc.find({'nums': {'$exists': true}}) gibt falsche Ergebnisse zurück (für das, was wir erreichen wollen).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': {'$exists': true}}).count()
1005

- -

db.doc.find({'nums.0': {'$exists': true}})Gibt korrekte Ergebnisse zurück, ist aber auch bei Verwendung eines vollständigen Erfassungsscans langsam (Hinweisphase COLLSCANin der Erklärung).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': {'$exists': true}}).explain()
{
  "queryPlanner": {
    "plannerVersion": 1,
    "namespace": "test.doc",
    "indexFilterSet": false,
    "parsedQuery": {
      "nums.0": {
        "$exists": true
      }
    },
    "winningPlan": {
      "stage": "COLLSCAN",
      "filter": {
        "nums.0": {
          "$exists": true
        }
      },
      "direction": "forward"
    },
    "rejectedPlans": [ ]
  },
  "serverInfo": {
    "host": "MacBook-Pro",
    "port": 27017,
    "version": "3.0.14",
    "gitVersion": "08352afcca24bfc145240a0fac9d28b978ab77f3"
  },
  "ok": 1
}

- -

db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}})gibt falsche Ergebnisse zurück. Dies liegt an einem ungültigen Index-Scan, bei dem keine Dokumente weitergeleitet werden. Ohne den Index wird es wahrscheinlich genau, aber langsam sein.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $gt: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 0,
  "executionTimeMillisEstimate": 0,
  "works": 2,
  "advanced": 0,
  "needTime": 0,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "nums": {
            "$gt": {
              "$size": 0
            }
          }
        },
        {
          "nums": {
            "$exists": true
          }
        }
      ]
    },
    "nReturned": 0,
    "executionTimeMillisEstimate": 0,
    "works": 1,
    "advanced": 0,
    "needTime": 0,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 0,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 0,
      "executionTimeMillisEstimate": 0,
      "works": 1,
      "advanced": 0,
      "needTime": 0,
      "needFetch": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "({ $size: 0.0 }, [])"
        ]
      },
      "keysExamined": 0,
      "dupsTested": 0,
      "dupsDropped": 0,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

- -

db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}})gibt korrekte Ergebnisse zurück, aber die Leistung ist schlecht. Es führt technisch einen Index-Scan durch, rückt dann aber alle Dokumente vor und muss sie dann filtern.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $not: { '$size': 0 }}}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 2016,
  "advanced": 5,
  "needTime": 2010,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "nums": {
            "$exists": true
          }
        },
        {
          "$not": {
            "nums": {
              "$size": 0
            }
          }
        }
      ]
    },
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 2016,
    "advanced": 5,
    "needTime": 2010,
    "needFetch": 0,
    "saveState": 15,
    "restoreState": 15,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 2005,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 2005,
      "executionTimeMillisEstimate": 0,
      "works": 2015,
      "advanced": 2005,
      "needTime": 10,
      "needFetch": 0,
      "saveState": 15,
      "restoreState": 15,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "[MinKey, MaxKey]"
        ]
      },
      "keysExamined": 2015,
      "dupsTested": 2015,
      "dupsDropped": 10,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

- -

db.doc.find({'nums': { $exists: true, $ne: [] }})liefert korrekte Ergebnisse und ist etwas schneller, aber die Leistung ist immer noch nicht ideal. Es wird IXSCAN verwendet, das nur Dokumente mit einem vorhandenen Listenfeld erweitert, dann aber die leeren Listen einzeln herausfiltern muss.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $exists: true, $ne: [] }}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 1018,
  "advanced": 5,
  "needTime": 1011,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "$and": [
        {
          "$not": {
            "nums": {
              "$eq": [ ]
            }
          }
        },
        {
          "nums": {
            "$exists": true
          }
        }
      ]
    },
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 1017,
    "advanced": 5,
    "needTime": 1011,
    "needFetch": 0,
    "saveState": 15,
    "restoreState": 15,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 1005,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 1005,
      "executionTimeMillisEstimate": 0,
      "works": 1016,
      "advanced": 1005,
      "needTime": 11,
      "needFetch": 0,
      "saveState": 15,
      "restoreState": 15,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "[MinKey, undefined)",
          "(undefined, [])",
          "([], MaxKey]"
        ]
      },
      "keysExamined": 1016,
      "dupsTested": 1015,
      "dupsDropped": 10,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

- -

db.doc.find({'nums': { $gt: [] }})IST GEFÄHRLICH, WEIL ABHÄNGIG VON DEM VERWENDETEN INDEX UNERWARTETE ERGEBNISSE FÜHREN KÖNNEN. Dies liegt an einem ungültigen Index-Scan, bei dem keine Dokumente weitergeleitet werden.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ nums: 1 }).count()
0
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).hint({ _id: 1 }).count()
5

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: [] }}).explain('executionStats').executionStats.executionStages
{
  "stage": "KEEP_MUTATIONS",
  "nReturned": 0,
  "executionTimeMillisEstimate": 0,
  "works": 1,
  "advanced": 0,
  "needTime": 0,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "inputStage": {
    "stage": "FETCH",
    "filter": {
      "nums": {
        "$gt": [ ]
      }
    },
    "nReturned": 0,
    "executionTimeMillisEstimate": 0,
    "works": 1,
    "advanced": 0,
    "needTime": 0,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "docsExamined": 0,
    "alreadyHasObj": 0,
    "inputStage": {
      "stage": "IXSCAN",
      "nReturned": 0,
      "executionTimeMillisEstimate": 0,
      "works": 1,
      "advanced": 0,
      "needTime": 0,
      "needFetch": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "keyPattern": {
        "nums": 1
      },
      "indexName": "nums_1",
      "isMultiKey": true,
      "direction": "forward",
      "indexBounds": {
        "nums": [
          "([], BinData(0, ))"
        ]
      },
      "keysExamined": 0,
      "dupsTested": 0,
      "dupsDropped": 0,
      "seenInvalidated": 0,
      "matchTested": 0
    }
  }
}

- -

db.doc.find({'nums.0’: { $gt: -Infinity }}) Gibt korrekte Ergebnisse zurück, weist jedoch eine schlechte Leistung auf (verwendet einen vollständigen Sammlungsscan).

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).count()
5
MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums.0': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages
{
  "stage": "COLLSCAN",
  "filter": {
    "nums.0": {
      "$gt": -Infinity
    }
  },
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 2007,
  "advanced": 5,
  "needTime": 2001,
  "needFetch": 0,
  "saveState": 15,
  "restoreState": 15,
  "isEOF": 1,
  "invalidates": 0,
  "direction": "forward",
  "docsExamined": 2005
}

- -

db.doc.find({'nums': { $gt: -Infinity }})überraschenderweise funktioniert das sehr gut! Es liefert die richtigen Ergebnisse und ist schnell und rückt 5 Dokumente aus der Index-Scan-Phase vor.

MacBook-Pro(mongod-3.0.14) test> db.doc.find({'nums': { $gt: -Infinity }}).explain('executionStats').executionStats.executionStages
{
  "stage": "FETCH",
  "nReturned": 5,
  "executionTimeMillisEstimate": 0,
  "works": 16,
  "advanced": 5,
  "needTime": 10,
  "needFetch": 0,
  "saveState": 0,
  "restoreState": 0,
  "isEOF": 1,
  "invalidates": 0,
  "docsExamined": 5,
  "alreadyHasObj": 0,
  "inputStage": {
    "stage": "IXSCAN",
    "nReturned": 5,
    "executionTimeMillisEstimate": 0,
    "works": 15,
    "advanced": 5,
    "needTime": 10,
    "needFetch": 0,
    "saveState": 0,
    "restoreState": 0,
    "isEOF": 1,
    "invalidates": 0,
    "keyPattern": {
      "nums": 1
    },
    "indexName": "nums_1",
    "isMultiKey": true,
    "direction": "forward",
    "indexBounds": {
      "nums": [
        "(-inf.0, inf.0]"
      ]
    },
    "keysExamined": 15,
    "dupsTested": 15,
    "dupsDropped": 10,
    "seenInvalidated": 0,
    "matchTested": 0
  }
}
wojcikstefan
quelle
Vielen Dank für Ihre sehr detaillierte Antwort @wojcikstefan. Leider scheint Ihre vorgeschlagene Lösung in meinem Fall nicht zu funktionieren. Ich habe eine MongoDB 3.6.4-Sammlung mit 2 Millionen Dokumenten, von denen die meisten ein seen_eventsString-Array haben, das ebenfalls indiziert ist. Bei der Suche mit { $gt: -Infinity }bekomme ich sofort 0 Dokumente. Mit { $exists: true, $ne: [] }I erhalten Sie die wahrscheinlicheren 1,2 Millionen Dokumente, wobei in der FETCH-Phase viel Zeit verschwendet wird: gist.github.com/N-Coder/b9e89a925e895c605d84bfeed648d82c
NCode
Es scheint, dass Sie Recht haben @Ncode - dies funktioniert nicht mehr in MongoDB v3.6 :( Ich habe ein paar Minuten damit herumgespielt und Folgendes gefunden: 1. db.test_collection.find({"seen_events.0": {$exists: true}})ist schlecht, weil es einen Sammlungsscan verwendet. 2. db.test_collection.find({seen_events: {$exists: true, $ne: []}})ist schlecht, weil sein IXSCAN mit allen Dokumenten übereinstimmt und dann die Filterung in der langsamen FETCH-Phase durchgeführt wird. 3. Gleiches gilt für db.test_collection.find({seen_events: {$exists: true, $not: {$size: 0}}}). 4. Alle anderen Abfragen geben ungültige Ergebnisse zurück.
wojcikstefan
1
@NCode hat eine Lösung gefunden! Wenn Sie sicher sind, dass alle nicht leeren seen_eventsZeichenfolgen enthalten, können Sie Folgendes verwenden : db.test_collection.find({seen_events: {$gt: ''}}).count(). Überprüfen Sie, ob die Leistung gut ist db.test_collection.find({seen_events: {$gt: ''}}).explain(true).executionStats. Sie können wahrscheinlich erzwingen, dass gesehene Ereignisse Zeichenfolgen sind, und zwar über die Schemaüberprüfung
wojcikstefan
Vielen Dank! Alle vorhandenen Werte sind Zeichenfolgen, daher werde ich das ausprobieren. Es gibt auch einen Fehler, der dieses Problem im MongoDB-Bugtracker diskutiert
NCode
30

Ab Version 2.6 können Sie das Feld auch mit einem leeren Array vergleichen:

ME.find({pictures: {$gt: []}})

Testen Sie es in der Shell:

> db.ME.insert([
{pictures: [1,2,3]},
{pictures: []},
{pictures: ['']},
{pictures: [0]},
{pictures: 1},
{foobar: 1}
])

> db.ME.find({pictures: {$gt: []}})
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a7"), "pictures": [ 1, 2, 3 ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4a9"), "pictures": [ "" ] }
{ "_id": ObjectId("54d4d9ff96340090b6c1c4aa"), "pictures": [ 0 ] }

Es enthält also ordnungsgemäß die Dokumente, in denen picturesmindestens ein Array-Element vorhanden ist, und schließt die Dokumente aus, in denen picturesentweder ein leeres Array oder kein Array vorhanden ist oder fehlt.

JohnnyHK
quelle
7
VORSICHT Diese Antwort kann zu Problemen führen, wenn Sie versuchen, Indizes zu verwenden. Tun db.ME.createIndex({ pictures: 1 })und dann db.ME.find({pictures: {$gt: []}})wird null Ergebnisse zurückgeben, zumindest in MongoDB v3.0.14
wojcikstefan
@wojcikstefan Guter Fang. Ich muss mir das noch einmal genauer ansehen.
JohnnyHK
5

Sie können eine der folgenden Methoden verwenden, um dies zu erreichen.
Beide sorgen auch dafür, dass für Objekte, die nicht den angeforderten Schlüssel enthalten, kein Ergebnis zurückgegeben wird:

db.video.find({pictures: {$exists: true, $gt: {$size: 0}}})
db.video.find({comments: {$exists: true, $not: {$size: 0}}})
Paul Imisi
quelle
4

Rufen Sie alle und nur die Dokumente ab, bei denen 'Bilder' ein Array ist und nicht leer

ME.find({pictures: {$type: 'array', $ne: []}})

Wenn Sie eine MongoDb-Version vor 3.2 verwenden , verwenden Sie $type: 4anstelle von $type: 'array'. Beachten Sie, dass diese Lösung nicht einmal $ size verwendet , sodass es kein Problem mit Indizes gibt ("Abfragen können keine Indizes für den $ size-Teil einer Abfrage verwenden").

Andere Lösungen, einschließlich dieser (akzeptierte Antwort):

ME.find ({images: {$ existiert: true, $ not: {$ size: 0}}}); ME.find ({images: {$ existiert: true, $ ne: []}})

sind falsch , weil sie Dokumente , auch wenn zum Beispiel zurückkehren, ‚Bilder‘ ist null, undefined, 0, usw.

SC1000
quelle
2

Verwenden Sie den $elemMatchOperator: gemäß der Dokumentation

Der Operator $ elemMatch vergleicht Dokumente, die ein Array-Feld enthalten, mit mindestens einem Element, das allen angegebenen Abfragekriterien entspricht.

$elemMatchesstellt sicher, dass der Wert ein Array ist und nicht leer. Die Abfrage wäre also so etwas wie

ME.find({ pictures: { $elemMatch: {$exists: true }}})

PS Eine Variante dieses Codes finden Sie im M121-Kurs der MongoDB University.

Andres Moreno
quelle
0

Sie können auch die Hilfsmethode Exists verwenden, wenn der Mongo-Operator $ existiert

ME.find()
    .exists('pictures')
    .where('pictures').ne([])
    .sort('-created')
    .limit(10)
    .exec(function(err, results){
        ...
    });
Iss bei Joes
quelle
0
{ $where: "this.pictures.length > 1" }

Verwenden Sie $ where und übergeben Sie this.field_name.length, das die Größe des Array-Felds zurückgibt, und überprüfen Sie es, indem Sie es mit number vergleichen. Wenn ein Array einen Wert als die Arraygröße hat, muss es mindestens 1 sein. Wenn also alle Arrayfelder eine Länge von mehr als eins haben, bedeutet dies, dass einige Daten in diesem Array enthalten sind

Prabhat Yadav
quelle
-8
ME.find({pictures: {$exists: true}}) 

So einfach war das, das hat bei mir funktioniert.

Luis Fletes
quelle