sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB $indexOfArray

En MongoDB, el $indexOfArray El operador de canalización de agregación busca en una matriz una aparición de un valor especificado y devuelve el índice de matriz de la primera aparición.

Sintaxis

La sintaxis es así:

{ $indexOfArray: [ <array expression>, <search expression>, <start>, <end> ] }

donde:

  • <array expression> es la matriz a buscar.
  • <search expression> es el valor que desea encontrar en la matriz.
  • <start> es un argumento opcional que especifica un punto de partida para buscar en la matriz. Puede ser cualquier expresión válida que se resuelva en un número entero no negativo.
  • <end> es un argumento opcional que especifica una posición de índice final para la búsqueda. Puede ser cualquier expresión válida que se resuelva en un número entero no negativo.

En MongoDB, las matrices se basan en cero, por lo que el recuento del índice comienza en cero (0 ).

Si no se encuentra el valor especificado, $indexOfArray devuelve -1 .

Si hay varias instancias del valor especificado, solo se devuelve la primera.

Ejemplo

Supongamos que tenemos una colección llamada products con los siguientes documentos:

{ "_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 ] }

Aquí hay un ejemplo de cómo aplicar $indexOfArray a esos documentos:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Resultado:

{ "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 }

En los primeros dos documentos, el valor de búsqueda se encontró en la posición 0 (las matrices están basadas en cero).

En el tercer documento, se encontró en la posición 1 . Observe que la búsqueda fue para una coincidencia exacta. No devolvió la posición 0 , aunque el valor en la posición 0 contiene el valor de búsqueda (es decir, XXS contiene XS ).

El valor de búsqueda no se encontró en los dos últimos documentos, por lo que -1 fue devuelto.

Aquí hay otro ejemplo, excepto que esta vez buscamos un valor numérico:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", 15 ] }
          }
     }
   ]
)

Resultado:

{ "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 }

Especifique una posición inicial

Puede proporcionar un tercer argumento para especificar una posición de índice inicial para la búsqueda.

Ejemplo:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 4, 5 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", 15, 1 ] }
          }
     }
   ]
)

Resultado:

{ "sizes" : [ 10, 12, 15 ], "result" : 2 }
{ "sizes" : [ 15, 16, 20 ], "result" : -1 }

En este caso, la expresión de búsqueda no se encontró en el segundo documento (documento 5). Esto se debe a que comenzamos la búsqueda en la posición 1 , y aunque ese documento contiene la expresión de búsqueda, está en la posición 0 (antes de la posición inicial de la búsqueda).

Especifique una posición final

También puede proporcionar un cuarto argumento para especificar la posición final del índice para la búsqueda.

Si proporciona este argumento, también debe proporcionar una posición inicial. Si no lo hace, este argumento se interpretará como el punto de partida.

Ejemplo:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS", 0, 1 ] }
          }
     }
   ]
)

Resultado:

{ "sizes" : [ "XS", "M", "L" ], "result" : 0 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : -1 }

El tercer documento devolvió -1 lo que significa que no se encontró la expresión de búsqueda.

Esto es lo que sucede si incrementamos la posición final del índice en 1:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS", 0, 2 ] }
          }
     }
   ]
)

Resultado:

{ "sizes" : [ "XS", "M", "L" ], "result" : 0 }
{ "sizes" : [ "XS", "S", "L", "XL" ], "result" : 0 }
{ "sizes" : [ "XXS", "XS", "M", "XL" ], "result" : 1 }

Esta vez se incluyó el valor y se devolvió su posición de índice.

Arreglos vacíos

Buscar una matriz vacía devuelve -1 .

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 6 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Resultado:

{ "sizes" : [ ], "result" : -1 }

Campos faltantes

Si el campo no está en el documento, $indexOfArray devuelve null .

Supongamos que tenemos el siguiente documento:

{ "_id" : 8, "prod" : "Map" }

Esto es lo que sucede cuando aplicamos $indexOfArray :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 8 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Resultado:

{ "result" : null }

Valores nulos

Si la expresión de la matriz es null (en lugar de una matriz), $indexOfArray devuelve null .

Supongamos que tenemos el siguiente documento:

{ "_id" : 7, "prod" : "Lap", "sizes" : null }

Esto es lo que sucede cuando aplicamos $indexOfArray :

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 7 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XS" ] }
          }
     }
   ]
)

Resultado:

{ "sizes" : null, "result" : null }

Sin embargo, cuando la expresión de búsqueda es null , el resultado es -1 , a menos que la expresión de matriz también sea null o falta su campo:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 1, 2, 3, 4, 5, 6, 7, 8 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", null ] }
          }
     }
   ]
)

Resultado:

{ "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 de datos incorrecto

Si la expresión de la matriz es del tipo de datos incorrecto, $indexOfArray devuelve un error.

Supongamos que tenemos el siguiente documento:

{ "_id" : 9, "prod" : "Box", "sizes" : "XXL" }

Esto es lo que sucede cuando aplicamos $indexOfArray a ese documento:

db.products.aggregate(
   [
     { $match: { _id: { $in: [ 9 ] } } },
     {
       $project:
          {
            _id: 0,
            sizes: 1,
            result: { $indexOfArray: [ "$sizes", "XXL" ] }
          }
     }
   ]
)

Resultado:

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

Como indica el mensaje de error, $indexOfArray requires an array as a first argument .