In MongoDB, il $in
l'operatore della pipeline di aggregazione restituisce un valore booleano che indica se un valore specificato è nella matrice.
Il $in
l'operatore della pipeline di aggregazione non deve essere confuso con $in
operatore di query, che seleziona i documenti in cui il valore di un campo è uguale a qualsiasi valore nella matrice specificata.
Esempio
Supponiamo di avere una collezione chiamata products
con i seguenti documenti:
{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL", "XXL" ] } { "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "L", "XL" ] } { "_id" : 3, "prod" : "Cap", "sizes" : [ "XS", "S", "M", "L", "XL" ] }
Possiamo usare il $in
operatore per scoprire se le sizes
sono o meno il campo contiene il valore L
.
Esempio:
db.products.aggregate(
[
{
$project:
{
hasLarge: { $in: [ "L", "$sizes" ] }
}
}
]
)
Risultato:
{ "_id" : 1, "hasLarge" : false } { "_id" : 2, "hasLarge" : true } { "_id" : 3, "hasLarge" : true }
Il secondo argomento deve risolversi in un array
Il secondo argomento di $in
l'operatore deve risolversi in un array. In caso contrario, viene restituito un errore.
Supponiamo di aggiungere il seguente documento alla raccolta:
{ "_id" : 4, "prod" : "Shirt", "sizes" : "L" }
Nota che le sizes
campo non è un array:è una stringa.
Applichiamo $in
a quel documento:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 4 ] } } },
{
$project:
{
hasLarge: { $in: [ "L", "$sizes" ] }
}
}
]
)
Risultato:
Error: command failed: { "ok" : 0, "errmsg" : "$in requires an array as a second argument, found: string", "code" : 40081, "codeName" : "Location40081" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
In questo caso, le sizes
campo contiene una stringa., e quindi viene restituito un errore.
In questo esempio, utilizzo anche $in
con il $match
operatore per filtrare i documenti solo per quelli che mi interessano. Nota che questo utilizza il $in
sintassi dell'operatore di query, che accetta un singolo argomento e non deve essere confusa con la sintassi dei due argomenti.
Valori Nulli
La stessa cosa accadrà se il secondo argomento è null
.
Aggiungiamo alla raccolta il seguente documento:
{ "_id" : 5, "prod" : "Jeans", "sizes" : null }
Ecco cosa succede se proviamo a utilizzare $in
con quel documento:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 5 ] } } },
{
$project:
{
hasLarge: { $in: [ "L", "$sizes" ] }
}
}
]
)
Risultato:
Error: command failed: { "ok" : 0, "errmsg" : "$in requires an array as a second argument, found: null", "code" : 40081, "codeName" : "Location40081" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Stesso errore.
Campi mancanti
Lo stesso vale per i campi mancanti.
Supponiamo di aggiungere il seguente documento alla nostra raccolta:
{ "_id" : 6, "prod" : "Shorts" }
E ora proviamo ad applicare $in
alle (inesistenti) sizes
campo:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
hasLarge: { $in: [ "L", "$sizes" ] }
}
}
]
)
Risultato:
Error: command failed: { "ok" : 0, "errmsg" : "$in requires an array as a second argument, found: missing", "code" : 40081, "codeName" : "Location40081" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Espressioni regolari
A differenza di $in
operatore di query, il $in
l'operatore della pipeline di aggregazione non supporta l'uso di espressioni regolari.
Pertanto, il codice seguente non risulta in una corrispondenza:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
hasLarge: { $in: [ /^X/, "$sizes" ] }
}
}
]
)
Risultato:
{ "_id" : 1, "hasLarge" : false } { "_id" : 2, "hasLarge" : false } { "_id" : 3, "hasLarge" : false }
Il risultato per tutti i documenti è false
, anche se le sizes
campo in tutti e tre i documenti contiene elementi di matrice che iniziano con la X
maiuscola .