In MongoDB, il $indexOfArray
l'operatore della pipeline di aggregazione cerca in una matrice un'occorrenza di un valore specificato e restituisce l'indice della matrice della prima occorrenza.
Sintassi
La sintassi è questa:
{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }
Dove:
<array expression>
è l'array da cercare.<search expression>
è il valore che vuoi trovare nell'array.<start>
è un argomento facoltativo che specifica un punto di partenza per cui eseguire la ricerca nell'array. Può essere qualsiasi espressione valida che si risolve in un numero intero non negativo.<end>
è un argomento facoltativo che specifica una posizione di indice finale per la ricerca. Può essere qualsiasi espressione valida che si risolve in un numero intero non negativo.
In MongoDB, gli array sono a base zero, quindi il conteggio dell'indice inizia da zero (0
).
Se il valore specificato non viene trovato, $indexOfArray
restituisce -1
.
Se sono presenti più istanze del valore specificato, viene restituita solo la prima.
Esempio
Supponiamo di avere una collezione chiamata products
con i seguenti documenti:
{ "_id" : 1, "prod" : "Bat", "sizes" : [ "XS", "M", "L" ] } { "_id" : 2, "prod" : "Hat", "sizes" : [ "XS", "S", "L", "XL" ] } { "_id" : 3, "prod" : "Cap", "sizes" : [ "XXS", "XS", "M", "XL" ] } { "_id" : 4, "prod" : "Zap", "sizes" : [ 10, 12, 15 ] } { "_id" : 5, "prod" : "Tap", "sizes" : [ 15, 16, 20 ] }
Ecco un esempio di applicazione di $indexOfArray
a quei documenti:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Risultato:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 } { "sizes" : [ 10, 12, 15 ], "result" : -1 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
Nei primi due documenti, il valore di ricerca è stato trovato nella posizione 0
(gli array sono a base zero).
Nel terzo documento, è stato trovato nella posizione 1
. Si noti che la ricerca era per una corrispondenza esatta. Non ha restituito la posizione 0
, anche se il valore nella posizione 0
contiene il valore di ricerca (ovvero XXS
contiene XS
).
Il valore di ricerca non è stato trovato negli ultimi due documenti, quindi -1
è stato restituito.
Ecco un altro esempio, tranne che questa volta cerchiamo un valore numerico:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15 ] }
}
}
]
)
Risultato:
{ "sizes" : [ "XS", "M", "L" ], "result" : -1 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 } { "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : 0 }
Specifica una posizione di partenza
Puoi fornire un terzo argomento per specificare una posizione di indice iniziale per la ricerca.
Esempio:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 4, 5 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", 15, 1 ] }
}
}
]
)
Risultato:
{ "sizes" : [ 10, 12, 15 ], "result" : 2 } { "sizes" : [ 15, 16, 20 ], "result" : -1 }
In questo caso, l'espressione di ricerca non è stata trovata nel secondo documento (documento 5). Questo perché abbiamo iniziato la ricerca nella posizione 1
, e sebbene quel documento contenga l'espressione di ricerca, si trova nella posizione 0
(prima della posizione di partenza per la ricerca).
Specifica una posizione finale
Puoi anche fornire un quarto argomento per specificare la posizione dell'indice finale per la ricerca.
Se fornisci questo argomento, devi anche fornire una posizione di partenza. In caso contrario, questo argomento verrà interpretato come punto di partenza.
Esempio:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
}
}
]
)
Risultato:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }
Il terzo documento ha restituito -1
il che significa che l'espressione di ricerca non è stata trovata.
Ecco cosa succede se incrementiamo la posizione dell'indice finale di 1:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
}
}
]
)
Risultato:
{ "sizes" : [ "XS", "M", "L" ], "result" : 0 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }
Questa volta il valore è stato incluso e la sua posizione di indice è stata restituita.
Matrici vuote
La ricerca in un array vuoto restituisce -1
.
db.products.aggregate(
[
{ $match: { _id: { $in: [ 6 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Risultato:
{ "sizes" : [ ], "result" : -1 }
Campi mancanti
Se il campo non è nel documento, $indexOfArray
restituisce null
.
Supponiamo di avere il seguente documento:
{ "_id" : 8, "prod" : "Map" }
Ecco cosa succede quando applichiamo $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Risultato:
{ "result" : null }
Valori Nulli
Se l'espressione della matrice è null
(invece di un array), $indexOfArray
restituisce null
.
Supponiamo di avere il seguente documento:
{ "_id" : 7, "prod" : "Lap", "sizes" : null }
Ecco cosa succede quando applichiamo $indexOfArray
:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 7 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XS" ] }
}
}
]
)
Risultato:
{ "sizes" : null, "result" : null }
Tuttavia, quando l'espressione di ricerca è null
, il risultato è -1
, a meno che anche l'espressione della matrice sia null
oppure manca il suo campo:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", null ] }
}
}
]
)
Risultato:
{ "sizes" : [ "XS", "M", "L" ], "result" : -1 } { "sizes" : [ "XS", "S", "L", "XL" ], "result" : -1 } { "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 } { "sizes" : [ 10, 12, 15 ], "result" : -1 } { "sizes" : [ 15, 16, 20 ], "result" : -1 } { "sizes" : [ ], "result" : -1 } { "sizes" : null, "result" : null } { "result" : null }
Tipo di dati errato
Se l'espressione dell'array è del tipo di dati errato, $indexOfArray
restituisce un errore.
Supponiamo di avere il seguente documento:
{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }
Ecco cosa succede quando applichiamo $indexOfArray
a quel documento:
db.products.aggregate(
[
{ $match: { _id: { $in: [ 9 ] } } },
{
$project:
{
_id: 0,
sizes: 1,
result: { $indexOfArray: [ "$sizes", "XXL" ] }
}
}
]
)
Risultato:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$indexOfArray requires an array as a first argument, found: string", "code" : 40090, "codeName" : "Location40090" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:639:17 [email protected]/mongo/shell/assert.js:729:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1058:12 @(shell):1:1
Come afferma il messaggio di errore, $indexOfArray requires an array as a first argument
.