Docs Menu
Docs Home
/ /

$fill (etapa de agregación)

$fill

Novedades en la versión 5.3.

Rellena null y los valores de campo faltantes dentro de los documentos.

Puedes utilizar $fill Para rellenar los puntos de datos faltantes:

  • En una secuencia basada en valores circundantes.

  • Con un valor fijo.

La etapa tiene esta $fill sintaxis:

{
$fill: {
partitionBy: <expression>,
partitionByFields: [ <field 1>, <field 2>, ... , <field n> ],
sortBy: {
<sort field 1>: <sort order>,
<sort field 2>: <sort order>,
...,
<sort field n>: <sort order>
},
output: {
<field 1>: { value: <expression> },
<field 2>: { method: <string> },
...
}
}
}

La etapa $fill toma un documento con estos campos:

Campo
Necesidad
Descripción

partitionBy

Opcional

Especifica una expresión para agrupar los documentos. En la etapa, un grupo $fill de documentos se denomina partición.

Si omite partitionBy y partitionByFields, $fill utiliza una partición para toda la colección.

partitionBy y partitionByFields son mutuamente excluyentes.

Vea un ejemplo.

Opcional

Especifica una matriz de campos como clave compuesta para agrupar los documentos. En la etapa, cada grupo $fill de documentos se denomina partición.

Si omite partitionBy y partitionByFields, $fill utiliza una partición para toda la colección.

partitionBy y partitionByFields son mutuamente excluyentes.

Ver partitionByFields Restricciones.

Obligatorio si el método se especifica en al menos una salida..<field>

De lo contrario, opcional.

Especifica el campo o los campos para ordenar los documentos dentro de cada partición. Utiliza la misma sintaxis que la $sort etapa.

Requerido

Especifica un objeto que contiene cada campo para el que se deben rellenar los valores faltantes. Se pueden especificar varios campos en el objeto de salida.

El nombre del objeto es el nombre del campo que se rellenará. El valor del objeto especifica cómo se rellenará el campo.

Requerido

Especifica un objeto que indica cómo completar los valores faltantes en el campo de destino.

El nombre del objeto debe ser value o method. Si el nombre es:

$fill devuelve un error si hay algún nombre de campo en la matriz partitionByFields:

  • Se evalúa como un valor que no es una cadena.

  • Comienza con $.

El linear método de relleno rellena null los campos y faltantes mediante interpolación lineal basada en los valores circundantes nonull en la secuencia.

  • Para cada documento donde el campo es null o falta, linearFill rellena esos campos proporcionalmente al rango de valores faltantesnull entre los valores circundantes que no son, según el orden sortBy. Para determinar los valores de los campos faltantes, linearFill utiliza:

    • La diferencia de los valores nonull circundantes.

    • El número de null campos a rellenar entre los valores circundantes.

  • El método linear puede rellenar múltiples valores consecutivos de null si dichos valores están precedidos y seguidos por valores que no seannull, de acuerdo con el orden sortBy.

    Ejemplo

    Si una colección contiene estos documentos:

    { index: 0, value: 0 },
    { index: 1, value: null },
    { index: 2, value: null },
    { index: 3, value: null },
    { index: 4, value: 10 }

    Después de utilizar el método de relleno linear para completar los valores null, los documentos se convierten en:

    { index: 0, value: 0 },
    { index: 1, value: 2.5 },
    { index: 2, value: 5 },
    { index: 3, value: 7.5 },
    { index: 4, value: 10 }
  • null Los valores que no están precedidos ni seguidos por valores distintos denull siguen siendo null.

  • Para utilizar el método de completado linear, también debes utilizar el campo sortBy para ordenar tus datos.

Para ver un ejemplo completo que utiliza el linear método de relleno, consulte Rellenar valores de campo faltantes con interpolación lineal.

locf corresponde a la última observación trasladada.

  • Si un campo que se está completando contiene null valores y no nulos, locf establece los null valores y faltantes en el último valor no nulo conocido del campo según el orden sortBy.

    • Si el campo contiene solo null o valores faltantes en una partición, locf establece el valor del campo en null para esa partición.

    • null y los valores de campo faltantes que aparecen antes de valores no nulos en el orden de clasificación permanecen como null.

  • Para utilizar el método de completado locf, también debes utilizar el campo sortBy para ordenar tus datos.

Para ver un ejemplo completo que utiliza el locf método de relleno, consulte Rellenar valores de campo faltantes según el último valor observado.

Para completar null y los valores de campos faltantes dentro de un documento puedes usar:

  • La $fill etapa.

    Cuando utiliza la etapa, el campo que especifica en la salida es el mismo campo utilizado como datos de $fill origen.

  • Los operadores de agregación $linearFill $locf y.

    Cuando usa o, puede establecer valores para un campo diferente del campo utilizado como datos de $linearFill $locforigen.

Los ejemplos de esta sección muestran cómo utilizar para completar valores $fill faltantes:

Una zapatería mantiene una colección dailySales que contiene un documento que resume las ventas diarias. La zapatería vende estos tipos de zapatos:

  • boots

  • sandals

  • sneakers

Cree la siguiente colección dailySales:

db.dailySales.insertMany( [
{
"date": ISODate("2022-02-02"),
"bootsSold": 10,
"sandalsSold": 20,
"sneakersSold": 12
},
{
"date": ISODate("2022-02-03"),
"bootsSold": 7,
"sneakersSold": 18
},
{
"date": ISODate("2022-02-04"),
"sneakersSold": 5
}
] )

No todos los documentos en la colección dailySales contienen cada tipo de zapato. Si falta un tipo de zapato, significa que no se vendieron zapatos de ese tipo en la fecha correspondiente.

El siguiente ejemplo utiliza para establecer las cantidades vendidas $fill en 0 para los tipos de zapatos faltantes para las ventas de cada día:

db.dailySales.aggregate( [
{
$fill:
{
output:
{
"bootsSold": { value: 0 },
"sandalsSold": { value: 0 },
"sneakersSold": { value: 0 }
}
}
}
] )

En el pipeline anterior:

  • $fill Completa los valores de los campos faltantes.

  • La salida especifica:

  • Los nombres de los campos a rellenar.

  • El valor que se debe establecer en los campos rellenados. En este ejemplo,
    La salida especifica un valor constante de 0.

Ejemplo de salida:

[
{
_id: ObjectId("6202df9f394d47411658b51e"),
date: ISODate("2022-02-02T00:00:00.000Z"),
bootsSold: 10,
sandalsSold: 20,
sneakersSold: 12
},
{
_id: ObjectId("6202df9f394d47411658b51f"),
date: ISODate("2022-02-03T00:00:00.000Z"),
bootsSold: 7,
sneakersSold: 18,
sandalsSold: 0
},
{
_id: ObjectId("6202df9f394d47411658b520"),
date: ISODate("2022-02-04T00:00:00.000Z"),
sneakersSold: 5,
bootsSold: 0,
sandalsSold: 0
}
]

Cree una colección stock que contenga los siguientes documentos, que rastrean el precio de las acciones de una sola empresa en intervalos de una hora:

db.stock.insertMany( [
{
time: ISODate("2021-03-08T09:00:00.000Z"),
price: 500
},
{
time: ISODate("2021-03-08T10:00:00.000Z"),
},
{
time: ISODate("2021-03-08T11:00:00.000Z"),
price: 515
},
{
time: ISODate("2021-03-08T12:00:00.000Z")
},
{
time: ISODate("2021-03-08T13:00:00.000Z")
},
{
time: ISODate("2021-03-08T14:00:00.000Z"),
price: 485
}
] )

Falta el campo price para algunos de los documentos de la colección.

Para completar los price valores faltantes mediante interpolación lineal, utilice con $fill el linear método de relleno:

db.stock.aggregate( [
{
$fill:
{
sortBy: { time: 1 },
output:
{
"price": { method: "linear" }
}
}
}
] )

En el pipeline anterior:

  • $fill Completa los valores de los campos faltantes.

  • sortBy: { time: 1 } ordena los documentos por el campo time en orden ascendente, del más antiguo al más reciente.

  • La salida especifica:

  • price como el campo en el que se deben rellenar los valores faltantes.

  • { method: "linear" } como método de relleno. El relleno linear
    El método completa price los valores faltantes mediante interpolación lineal basada en los price valores circundantes en la secuencia.

Ejemplo de salida:

[
{
_id: ObjectId("620ad41c394d47411658b5e9"),
time: ISODate("2021-03-08T09:00:00.000Z"),
price: 500
},
{
_id: ObjectId("620ad41c394d47411658b5ea"),
time: ISODate("2021-03-08T10:00:00.000Z"),
price: 507.5
},
{
_id: ObjectId("620ad41c394d47411658b5eb"),
time: ISODate("2021-03-08T11:00:00.000Z"),
price: 515
},
{
_id: ObjectId("620ad41c394d47411658b5ec"),
time: ISODate("2021-03-08T12:00:00.000Z"),
price: 505
},
{
_id: ObjectId("620ad41c394d47411658b5ed"),
time: ISODate("2021-03-08T13:00:00.000Z"),
price: 495
},
{
_id: ObjectId("620ad41c394d47411658b5ee"),
time: ISODate("2021-03-08T14:00:00.000Z"),
price: 485
}
]

Cree una colección restaurantReviews que contenga los siguientes documentos, que almacenan puntuaciones de reseñas de un solo restaurante a lo largo del tiempo:

db.restaurantReviews.insertMany( [
{
date: ISODate("2021-03-08"),
score: 90
},
{
date: ISODate("2021-03-09"),
score: 92
},
{
date: ISODate("2021-03-10")
},
{
date: ISODate("2021-03-11")
},
{
date: ISODate("2021-03-12"),
score: 85
},
{
date: ISODate("2021-03-13")
}
] )

Falta el campo score para algunos de los documentos de la colección.

Para rellenar los campos score faltantes y garantizar que no haya espacios en blanco en los datos, utilice$fill. En el siguiente ejemplo, $fillutiliza el método de relleno locf para rellenar los valores score faltantes con los valores score anteriores de la secuencia:

db.restaurantReviews.aggregate( [
{
$fill:
{
sortBy: { date: 1 },
output:
{
"score": { method: "locf" }
}
}
}
] )

En el pipeline anterior:

  • $fill completa los score valores faltantes.

  • sortBy: { date: 1 } ordena los documentos por el campo date en orden ascendente, del más antiguo al más reciente.

  • La salida especifica:

  • score como el campo en el que se deben rellenar los valores faltantes.

  • { method: "locf" } como método de relleno. El relleno locf
    El método rellena los valores score faltantes con el último score observado en la secuencia.

Ejemplo de salida:

[
{
_id: ObjectId("62040bc9394d47411658b553"),
date: ISODate("2021-03-08T00:00:00.000Z"),
score: 90
},
{
_id: ObjectId("62040bc9394d47411658b554"),
date: ISODate("2021-03-09T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b555"),
date: ISODate("2021-03-10T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b556"),
date: ISODate("2021-03-11T00:00:00.000Z"),
score: 92
},
{
_id: ObjectId("62040bc9394d47411658b557"),
date: ISODate("2021-03-12T00:00:00.000Z"),
score: 85
},
{
_id: ObjectId("62040bc9394d47411658b558"),
date: ISODate("2021-03-13T00:00:00.000Z"),
score: 85
}
]

Considere el ejemplo anterior con reseñas de restaurantes, pero en lugar de rastrear un solo restaurante, la colección ahora contiene reseñas de varios restaurantes.

Cree una colección llamada restaurantReviewsMultiple y complétela con estos documentos:

db.restaurantReviewsMultiple.insertMany( [
{
date: ISODate("2021-03-08"),
restaurant: "Joe's Pizza",
score: 90
},
{
date: ISODate("2021-03-08"),
restaurant: "Sally's Deli",
score: 75
},
{
date: ISODate("2021-03-09"),
restaurant: "Joe's Pizza",
score: 92
},
{
date: ISODate("2021-03-09"),
restaurant: "Sally's Deli"
},
{
date: ISODate("2021-03-10"),
restaurant: "Joe's Pizza"
},
{
date: ISODate("2021-03-10"),
restaurant: "Sally's Deli",
score: 68
},
{
date: ISODate("2021-03-11"),
restaurant: "Joe's Pizza",
score: 93
},
{
date: ISODate("2021-03-11"),
restaurant: "Sally's Deli"
}
] )

Falta el campo score para algunos de los documentos de la colección.

Para rellenar los campos score faltantes y garantizar que no haya espacios en blanco en los datos, utilice$fill. En el siguiente ejemplo, $fillutiliza el método de relleno locf para rellenar los valores score faltantes con los valores score anteriores de la secuencia:

db.restaurantReviewsMultiple.aggregate( [
{
$fill:
{
sortBy: { date: 1 },
partitionBy: { "restaurant": "$restaurant" },
output:
{
"score": { method: "locf" }
}
}
}
] )

En el pipeline anterior:

  • $fill completa los score valores faltantes.

  • sortBy: { date: 1 } ordena los documentos por el campo date en orden ascendente, del más antiguo al más reciente.

  • partitionBy: { "restaurant": "$restaurant" } Divide los datos por restaurant. Hay dos restaurantes: Joe's Pizza y Sally's Deli.

  • La salida especifica:

  • score como el campo en el que se deben rellenar los valores faltantes.

  • { method: "locf" } como método de relleno. El relleno locf
    El método rellena los valores score faltantes con el último score observado en la secuencia.

Ejemplo de salida:

[
{
_id: ObjectId("620559f4394d47411658b58f"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 90
},
{
_id: ObjectId("620559f4394d47411658b591"),
date: ISODate("2021-03-09T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 92
},
{
_id: ObjectId("620559f4394d47411658b593"),
date: ISODate("2021-03-10T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 92
},
{
_id: ObjectId("620559f4394d47411658b595"),
date: ISODate("2021-03-11T00:00:00.000Z"),
restaurant: "Joe's Pizza",
score: 93
},
{
_id: ObjectId("620559f4394d47411658b590"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 75
},
{
_id: ObjectId("620559f4394d47411658b592"),
date: ISODate("2021-03-09T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 75
},
{
_id: ObjectId("620559f4394d47411658b594"),
date: ISODate("2021-03-10T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 68
},
{
_id: ObjectId("620559f4394d47411658b596"),
date: ISODate("2021-03-11T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 68
}
]

Cuando se completan valores faltantes, la salida no indica si un valor fue completado con el operador $fill o si el valor existía originalmente en el documento. Para distinguir entre valores completados y preexistentes, puedes usar una etapa $set antes de $fill y establecer un nuevo campo en función de si el valor existe.

Por ejemplo, cree una colección restaurantReviews que contenga los siguientes documentos, que almacenan puntuaciones de reseñas de un restaurante a lo largo del tiempo:

db.restaurantReviews.insertMany( [
{
date: ISODate("2021-03-08"),
score: 90
},
{
date: ISODate("2021-03-09"),
score: 92
},
{
date: ISODate("2021-03-10")
},
{
date: ISODate("2021-03-11")
},
{
date: ISODate("2021-03-12"),
score: 85
},
{
date: ISODate("2021-03-13")
}
] )

Falta el campo score en algunos documentos de la colección. Puede completar los valores score faltantes con el operador $fill.

Cree una canalización para realizar las siguientes acciones:

  • Utilice para añadir un nuevo campo a cada documento que indique si el campo del $set documento score existía antes de que el $fill operador rellenara los valores. Este nuevo campo se valueExisted llama.

  • Rellene los valores faltantes score con la última observación score de la secuencia. El método de relleno locf significa "última observación transferida".

La tubería se parece al siguiente código:

db.restaurantReviews.aggregate( [
{
$set: {
"valueExisted": {
"$ifNull": [
{ "$toBool": { "$toString": "$score" } },
false
]
}
}
},
{
$fill: {
sortBy: { date: 1 },
output:
{
"score": { method: "locf" }
}
}
}
] )

Nota

Manejo de valores de cero

En la expresión,$ifNull los score valores se convierten en cadenas y luego en booleanos. La expresión siempre convierte $toBool las cadenas true en. Si los score valores no se convierten en cadenas, score los valores de 0 tendrán valueExisted establecido false en.

Salida:

[
{
_id: ObjectId("63595116b1fac2ee2e957f15"),
date: ISODate("2021-03-08T00:00:00.000Z"),
score: 90,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f16"),
date: ISODate("2021-03-09T00:00:00.000Z"),
score: 92,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f17"),
date: ISODate("2021-03-10T00:00:00.000Z"),
valueExisted: false,
score: 92
},
{
_id: ObjectId("63595116b1fac2ee2e957f18"),
date: ISODate("2021-03-11T00:00:00.000Z"),
valueExisted: false,
score: 92
},
{
_id: ObjectId("63595116b1fac2ee2e957f19"),
date: ISODate("2021-03-12T00:00:00.000Z"),
score: 85,
valueExisted: true
},
{
_id: ObjectId("63595116b1fac2ee2e957f1a"),
date: ISODate("2021-03-13T00:00:00.000Z"),
valueExisted: false,
score: 85
}
]

Cambiado en la versión 8.0.

A partir de MongoDB 8.0, $fill puede usar el método linear para interpolar si hay valores idénticos en diferentes particiones.

Cree la siguiente colección restaurantReviewsMultiple que contenga los siguientes documentos, que almacenan puntuaciones de reseñas de restaurantes en fechas idénticas:

db.restaurantReviewsMultiple.insertMany( [
{
date: ISODate("2021-03-08"),
restaurant: "Steve's Pizza",
score: 90
},
{
date: ISODate("2021-03-08"),
restaurant: "Sally's Deli",
score: 75
}
] )

El siguiente ejemplo de agregación utiliza "linear" para interpolar las fechas idénticas en las diferentes particiones:

db.restaurantReviewsMultiple.aggregate( [
{
$fill: {
sortBy: { date: 1 },
partitionBy: { "restaurant": "$restaurant" },
output: { "score": { method: "linear" } }
}
}
] )

A partir de MongoDB 8.1, el ejemplo devuelve la siguiente salida:

[
{
_id: ObjectId("620559f4394d47411658b590"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Sally's Deli",
score: 75
},
{
_id: ObjectId("620559f4394d47411658b58f"),
date: ISODate("2021-03-08T00:00:00.000Z"),
restaurant: "Steve's Pizza",
score: 90
}
]

Los ejemplos de Node.js en esta página utilizan la colección sample_weatherdata.data de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, se puede consultar Primeros pasos en la documentación del driver de MongoDB Node.js.

Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $fill a una canalización de agregación, utilice el Operador $fill en un objeto de canalización.

El siguiente ejemplo crea una canalización que completa valores nulos o faltantes. La canalización incluye las siguientes etapas:

  • La etapa agrupa los documentos de entrada por $group su ts campo y calcula el promedio de cada seaSurfaceTemperature.value grupo.

  • La etapa ordena los datos agrupados por $fill el _id campo en orden ascendente y completa los seaSurfaceTemperature valores nulos o faltantes mediante interpolación lineal.

const pipeline = [
{
$group: {
_id: "$ts",
seaSurfaceTemperature: { $avg: "$seaSurfaceTemperature.value" },
}
},
{
$fill: {
sortBy: { _id: 1 },
output: { seaSurfaceTemperature: { method: "linear" } }
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

Volver

$facet

En esta página