MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $indexOfArray

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 .