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

MongoDB $filtro

En MongoDB, el $filter El operador de canalización de agregación devuelve un subconjunto de una matriz en función de una condición específica.

El $filter El operador devuelve una matriz con solo aquellos elementos que coinciden con la condición, en su orden original.

Sintaxis

La sintaxis es así:

{ $filter: { input: <array>, as: <string>, cond: <expression> } }

Cada campo es como se explica a continuación.

Campo Especificación
input Una expresión que se resuelve en una matriz.
as Este es un campo opcional. Especifica un nombre para la variable que representa cada elemento individual de la input formación. Si no se especifica ningún nombre (es decir, si omite este campo), el nombre de la variable por defecto es this .
cond Una expresión que se resuelve en un valor booleano que se utiliza para determinar si un elemento debe incluirse en la matriz de salida. La expresión hace referencia a cada elemento de la input matriz individualmente con el nombre de variable especificado en as .

Ejemplo

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

{ "_id" : 1, "player" : "Homer", "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "player" : "Marge", "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "player" : "Bart", "scores" : [ 15, 11, 8 ] }

Aquí hay un ejemplo de cómo aplicar el $filter operador para filtrar los elementos de la matriz en las scores campo:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 1, 2, 3 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultado:

{ "_id" : 1, "highScores" : [ ] }
{ "_id" : 2, "highScores" : [ 17, 18 ] }
{ "_id" : 3, "highScores" : [ 15, 11 ] }

En este ejemplo, filtramos las matrices solo para aquellos elementos que tienen un valor superior a 10. Solo se devuelven esos valores.

Los valores inferiores a 10 se omiten del resultado. En el caso del primer documento, esto da como resultado una matriz vacía.

Aquí, usamos el as campo para nombrar la variable de retorno score . Luego nos referimos a esa variable en el cond campo usando $$score . Como se mencionó, puede omitir as y luego haga referencia a la variable de retorno usando $$this . Más sobre esto más adelante.

Arreglos vacíos

Si la matriz está vacía, se devuelve una matriz vacía.

Supongamos que tenemos el siguiente documento en nuestra colección:

{ "_id" : 4, "player" : "Farnsworth", "scores" : [ ] }

Esto es lo que sucede cuando aplicamos $filter a esa matriz:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 4 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultado:

{ "_id" : 4, "highScores" : [ ] }

Tipo incorrecto

Aplicando $filter a un campo que no contiene una matriz devuelve un error.

Ejemplo:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 4 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$player",
              as: "player",
              cond: { $gt: [ "$$player", 10 ] }
          }
        }
    }
  }
])

Resultado:

Error: command failed: {
	"ok" : 0,
	"errmsg" : "input to $filter must be an array not string",
	"code" : 28651,
	"codeName" : "Location28651"
} : 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

Valores nulos

Si el campo contiene null en lugar de una matriz, el resultado es null .

Imagina que tenemos el siguiente documento en la colección:

{ "_id" : 5, "player" : "Meg", "scores" : null }

Esto es lo que sucede cuando aplicamos $filter a las scores campo:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 5 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              as: "score",
              cond: { $gt: [ "$$score", 10 ] }
          }
        }
    }
  }
])

Resultado:

{ "_id" : 5, "highScores" : null }

Campo inexistente

Aplicando $filter a un campo que no existe da como resultado null siendo devuelto.

Ejemplo:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 5 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$name",
              as: "name",
              cond: { $gt: [ "$$name", 10 ] }
          }
        }
    }
  }
])

Resultado:

{ "_id" : 5, "highScores" : null }

El nombre de la variable es opcional

En los ejemplos anteriores, uso el as campo para asignar un nombre a la variable.

Como se mencionó, el as campo es opcional. Si omite este campo, el nombre de la variable por defecto es this .

He aquí un ejemplo:

db.players.aggregate([
  { 
    $match: { _id: { $in: [ 1, 2, 3 ] } } 
  },
  {
    $project: {
        highScores: {
          $filter: {
              input: "$scores",
              cond: { $gt: [ "$$this", 10 ] }
          }
        }
    }
  }
])

Resultado:

{ "_id" : 1, "highScores" : [ ] }
{ "_id" : 2, "highScores" : [ 17, 18 ] }
{ "_id" : 3, "highScores" : [ 15, 11 ] }

Esto es lo mismo que el primer ejemplo, excepto que en este ejemplo, omitimos as campo, y por lo tanto referirse a la variable usando $$this .