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
.