Abfrage nach Dokumenten mit einer Array-Größe größer als 1 in MongoDB

Tahseen Tauseef 20 Juni 2023
  1. Beispieldaten
  2. Verwenden Sie den $size-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen
  3. Verwenden Sie den $where-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen
  4. Verwenden Sie die Punktnotation, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen
  5. Verwenden Sie $expr (3.6+), um in MongoDB nach Dokumenten mit einer Array-Größe von mehr als 1 zu suchen
  6. Verwenden Sie den Aggregationsoperator $facet, um in MongoDB nach Dokumenten mit einer Arraygröße von mehr als 1 abzufragen
Abfrage nach Dokumenten mit einer Array-Größe größer als 1 in MongoDB

Wenn Sie an Projekten arbeiten, bei denen Sie die Array-Größe überprüfen oder ein Element finden müssen, dessen Größe größer oder kleiner als eine bestimmte Länge ist, können MongoDB-Operatoren wie $size, $where, $exists verwendet werden.

Die unten beschriebenen Ansätze können Ihnen dabei helfen, Ihr Problem mit der Array-Länge oder Array-Größe zu lösen.

Beispieldaten

Angenommen, wir haben die folgenden Daten. Wir werden diese Beispieldaten verwenden, um Dokumente mit einer bestimmten Array-Größe in MongoDB abzufragen.

db.inventory.insertMany([

{ item: "journal", qty: 25, tags: ["blank", "reds"], book: { author:`xyz`, price:50, location:[`india`, `USA`, `nepal`]} },

{ item: "notebook", qty: 50, tags: ["reds", "blank"], book: { author:`xyz`, price:50, location:[`india`, `usa`]} },

{ item: "paper", qty: 100, tags: ["reds", "blank", "plain"], book: { author:`xyz`, price:50, location:[]}},
{ item: "planner", qty: 75, tags: ["blank", "reds"], book: { author:`xyz`, price:50, location:[`india`]} },

{ item: "postcard", qty: 45, tags: ["blue"], book:{} }
]);

Verwenden Sie den $size-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen

Die Array-Operatorklasse in MongoDB umfasst viele Operatoren, die zum Abrufen von Dokumenten durch Bezugnahme auf Arrays verwendet werden; $size ist einer davon. Der Operator $size wird verwendet, um ein Dokument zu erhalten, das ein Array-Feld einer bestimmten Größe enthält.

Es funktioniert nur mit Arrays und akzeptiert numerische Werte als Parameter.

Im Folgenden sind die Hauptfunktionen des Operators $size aufgeführt:

  1. Es beginnt mit dem Vergleich eines Array-Felds mit der vom Benutzer angegebenen Größe und fährt dann fort.
  2. Es ruft die Dokumente ab, die die Felder enthalten, die den vorhergehenden Schritt erfüllen.

Syntax:

{array-field: {$size: <length-of-array>}}

In diesem Fall ist array-field der Name des gewünschten Felds in einem Dokument und length-of-array eine beliebige numerische Zahl, die der Länge entspricht.

Einige Beispiele werden unten geteilt, um zu sehen, wie der Operator $size in MongoDB verwendet wird.

Finden Sie Elemente, bei denen die tags-Länge 1 ist

db.inventory.find({tags:{$size:1}})

Ausgang:

$Größe 1

Elemente finden, bei denen die Länge von books.location 1 ist

db.inventory.find({books.location:{$size:1}}

Ausgang:

$Größe 2

Verwenden Sie den $where-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen

Um dem Abfragesystem eine Zeichenfolge bereitzustellen, die einen JavaScript-Ausdruck oder eine vollständige JavaScript-Funktion enthält, verwenden Sie den Operator $where. Es ermöglicht mehr Flexibilität, benötigt jedoch die Datenbank, um den JavaScript-Ausdruck oder die Funktion für jedes Dokument in der Sammlung auszuführen.

Verweisen Sie im JavaScript-Ausdruck oder in der JavaScript-Funktion auf den Datensatz, indem Sie entweder this oder obj verwenden.

Syntax:

{ $where: <string|JavaScript Code> }

Nachfolgend werden Beispiele gegeben, um die Funktionsweise des Operators $where zu zeigen.

Finden Sie Elemente, bei denen die tags-Länge 1 ist

db.inventory.find({tags:{$where:`this.tags.length == 1`}}

Ausgang:

$wo 1

Finden Sie Elemente, bei denen die Länge der tags größer oder gleich 1 ist

db.inventory.find({tags:{$where:`this.tags.length >= 1`}}

Elemente finden, bei denen die Länge von books.location 1 ist

you cannot check this with the help of $where

Verwenden Sie den Abfrageoperator $where nur für Dokumente der obersten Ebene. Es funktioniert nicht innerhalb einer verschachtelten Seite.

Verwenden Sie die Punktnotation, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen

Um auf Array-Elemente und die Felder eines eingebetteten Dokuments zuzugreifen, verwendet MongoDB die Punktnotation.

Greifen Sie auf Array-Elemente zu

Um ein Array-Element anhand seiner nullbasierten Indexposition anzugeben oder darauf zuzugreifen, verketten Sie den Array-Namen mit dem Punkt (.) und der nullbasierten Indexposition und schließen Sie ihn dann in Anführungszeichen ein.

Syntax:

"<array>.<index>"

Betrachten Sie beispielsweise das folgende Feld in einem Dokument.

{
   ...
   contribs: [ "Turing machine", "Turing test", "Turingery" ],
   ...
}

Verwenden Sie die Punktnotation "contribs.2", um das dritte Mitglied im contribs.2-Array zu identifizieren.

Finden Sie Elemente, bei denen die tags-Länge größer als 0 ist

db.inventory.find({tags.0:{$exists:true`}}
It will look for elements with at least one tag // array with a zero-based index.

Finden Sie Elemente, bei denen die Länge von books.location größer als 1 ist

db.invantory.find({book.location.1: {$exists:true}}
// It looks for all components in whose book. There are at least two elements to a place.

Verwenden Sie $expr (3.6+), um in MongoDB nach Dokumenten mit einer Array-Größe von mehr als 1 zu suchen

Syntax:

{ $expr: { <expression> } }

Dokument finden, bei dem die Länge von $tags größer als 0 ist

db.invantory.find({
    $expr: {
        $gt: [{ $size: { $ifNull: ["$tags", []] } }, 0]
    }
})

Finden Sie Elemente, bei denen die Länge von $books.location größer als 1 ist

db.invantory.find({
    $expr: {
        $gt: [{ $size: { $ifNull: ["$book.location", []] } }, 1]
    }
})
// $ifNull: ["$book.location", []] this is used to avoid any error if book.location is null

Verwenden Sie den Aggregationsoperator $facet, um in MongoDB nach Dokumenten mit einer Arraygröße von mehr als 1 abzufragen

Dieser Operator verarbeitet zahlreiche Aggregationen auf demselben Satz von Eingabedokumenten in einer einzigen Stufe. Jede Pipeline hat ihr eigenes Feld im Ausgabedokument, in dem die Ergebnisse als Array von Dokumenten gespeichert werden.

Die $facet-Stufe ermöglicht die Erstellung facettenreicher Aggregationen, die Daten über mehrere Dimensionen oder Facetten innerhalb einer einzigen Aggregationsstufe charakterisieren. Facettenreiche Aggregationen bieten mehrere Filter und Kategorisierungen, um das Durchsuchen und Analysieren von Daten zu unterstützen.

Beispielsweise verwenden Einzelhändler häufig Facetten, um Suchergebnisse zu reduzieren, indem sie Filter basierend auf Produktpreis, Hersteller, Größe usw. erstellen.

Eingabedokumente werden nur einmal an den Schritt $facet gesendet. $facet ermöglicht zahlreiche Aggregationen auf demselben Satz von Eingabedokumenten, ohne dass diese mehrmals abgerufen werden müssen.

Syntax:

{ $facet:
   {
      <outputField1>: [ <stage1>, <stage2>, ... ],
      <outputField2>: [ <stage1>, <stage2>, ... ],
      ...

   }
}

Geben Sie den Namen des Ausgabefelds für jede Pipeline ein.

Jede Unterpipeline in $facet erhält den identischen Satz von Eingabedokumenten. Diese Sub-Pipelines sind voneinander unabhängig, und die von ihnen erzeugten Dokumentarrays werden in unterschiedlichen Feldern des Ausgabedokuments gespeichert.

Innerhalb derselben $facet-Phase kann die Ausgabe einer Sub-Pipeline nicht als Eingabe für eine andere Sub-Pipeline verwendet werden. Fügen Sie zusätzliche Stufen nach $facet hinzu und geben Sie den Feldnamen outputField> der gewünschten Sub-Pipeline-Ausgabe an, wenn weitere Aggregationen erforderlich sind.

Index-Nutzung in der Phase $facet

Selbst wenn seine Sub-Pipelines $match verwenden oder wenn $facet der erste Schritt in der Pipeline ist, können die Stufe $facet und ihre Sub-Pipelines keine Indizes verwenden. Während der Ausführung führt die Stufe $facet immer einen COLLSCAN durch.

Stellen Sie sich einen Online-Shop vor, dessen Inventar in der folgenden artwork-Sammlung gespeichert ist:

{ "_id" : 1, "title" : "The Pillars of Society", "artists" : "Grosz", "year" : 1926,
  "price" : NumberDecimal("199.99"),
  "tags" : [ "painting", "satire", "Expressionism", "caricature" ] }
{ "_id" : 2, "title" : "Melancholy III", "artists" : "Munch", "year" : 1902,
  "price" : NumberDecimal("280.00"),
  "tags" : [ "woodcut", "Expressionism" ] }
{ "_id" : 3, "title" : "Dancer", "artists" : "Miro", "year" : 1925,
  "price" : NumberDecimal("76.04"),
  "tags" : [ "oil", "Surrealism", "painting" ] }
{ "_id" : 4, "title" : "The Great Wave off Kanagawa", "artists" : "Hokusai",
  "price" : NumberDecimal("167.30"),
  "tags" : [ "woodblock", "ukiyo-e" ] }
{ "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931,
  "price" : NumberDecimal("483.00"),
  "tags" : [ "Surrealism", "painting", "oil" ] }
{ "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913,
  "price" : NumberDecimal("385.00"),
  "tags" : [ "oil", "painting", "abstract" ] }
{ "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893,
  "tags" : [ "Expressionism", "painting", "oil" ] }
{ "_id" : 8, "title" : "Blue Flower", "artist" : "O`Keefe", "year" : 1918,
  "price" : NumberDecimal("118.42"),
  "tags" : [ "abstract", "painting" ] }

Das folgende Verfahren nutzt die Facettierungsfunktionen von MongoDB, um Verbrauchern den Lagerbestand des Geschäfts anzuzeigen, der nach Tags, Preis und Jahr der Erstellung geordnet ist. Diese $facet-Stufe besteht aus drei Sub-Pipelines, die diese facettenreiche Aggregation mit $sortByCount, $bucket oder $bucketAuto. durchführen.

Die Eingabedokumente von artwork werden nur einmal zu Beginn des Vorgangs aus der Datenbank abgerufen.

Beispiel:

db.artwork.aggregate( [
  {
    $facet: {
      "categorizedByTags": [
        { $unwind: "$tags" },
        { $sortByCount: "$tags" }
      ],
      "categorizedByPrice": [
        // Filter out documents without a price e.g., _id: 7
        { $match: { price: { $exists: 1 } } },
        {
          $bucket: {
            groupBy: "$price",
            boundaries: [  0, 150, 200, 300, 400 ],
            default: "Other",
            output: {
              "count": { $sum: 1 },
              "titles": { $push: "$title" }
            }
          }
        }
      ],
      "categorizedByYears(Auto)": [
        {
          $bucketAuto: {
            groupBy: "$year",
            buckets: 4
          }
        }
      ]
    }
  }
])

Ausgang:

$facette 1

Verwandter Artikel - MongoDB Query