Abfrage nach Dokumenten mit einer Array-Größe größer als 1 in MongoDB
- Beispieldaten
-
Verwenden Sie den
$size
-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen -
Verwenden Sie den
$where
-Operator, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen - Verwenden Sie die Punktnotation, um in MongoDB nach Dokumenten mit einer Array-Größe größer als 1 zu suchen
-
Verwenden Sie
$expr
(3.6+), um in MongoDB nach Dokumenten mit einer Array-Größe von mehr als 1 zu suchen -
Verwenden Sie den Aggregationsoperator
$facet
, um in MongoDB nach Dokumenten mit einer Arraygröße von mehr als 1 abzufragen
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:
- Es beginnt mit dem Vergleich eines Array-Felds mit der vom Benutzer angegebenen Größe und fährt dann fort.
- 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:
Elemente finden, bei denen die Länge von books.location
1 ist
db.inventory.find({books.location:{$size:1}}
Ausgang:
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:
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: