Docs Menu
Docs Home
/ /

$densificar (etapa de agregación)

$densify

Nuevo en la versión 5.1.

Crea nuevos documentos en una secuencia de documentos donde faltan ciertos valores en un campo.

Puedes utilizar $densify a:

  • Rellenar vacíos en datos de series de tiempo.

  • Agregar valores faltantes entre grupos de datos.

  • Complete sus datos con un rango específico de valores.

La etapa tiene esta $densify sintaxis:

{
$densify: {
field: <fieldName>,
partitionByFields: [ <field 1>, <field 2> ... <field n> ],
range: {
step: <number>,
unit: <time unit>,
bounds: < "full" || "partition" > || [ < lower bound >, < upper bound > ]
}
}
}

La etapa $densify toma un documento con estos campos:

Campo
Necesidad
Descripción

Campo

Requerido

El campo que se va a densificar. Los valores del field especificado deben ser todos numéricos o todas fechas.

Los documentos que no contienen el field especificado continúan a través del proceso sin modificaciones.

Para especificar un <field> en un documento incrustado o en un arreglo, utiliza notación de puntos.

Para conocer las field restricciones, consulte Restricciones.

Opcional

El conjunto de campos que actúa como clave compuesta para agrupar los documentos. En la etapa, cada grupo $densify de documentos se denomina partición.

Si omite este campo, utiliza una partición para toda la$densify colección.

Para ver un ejemplo, consulte Densificación con particiones.

Para conocer las partitionByFields restricciones, consulte Restricciones.

Requerido

Un objeto que especifica cómo se densifican los datos.

Requerido

Puede especificar range.bounds como:

  • An array: [ < lower bound >, < upper bound > ],

  • Una cadena: "full" o "partition".

Si bounds es una matriz:

  • $densify agrega documentos que abarcan el rango de valores dentro de los límites especificados.

  • El tipo de datos para los límites debe corresponder al tipo de datos del campo que se está densificando.

  • Para detalles sobre el comportamiento, consulta range.bounds Comportamiento.

Si bounds es "full":

  • $densify agrega documentos que abarcan todo el rango de valores del que field se está densificando.

Si bounds es "partition":

  • $densify agrega documentos a cada partición, de forma similar a si hubiera ejecutado una full densificación de rango en cada partición individualmente.

Requerido

La cantidad para incrementar el valor del campo en cada documento. crea un nuevo documento por$densify cada step entre los documentos existentes.

Si se especifica range.unit, step debe ser un entero. De lo contrario, step puede ser cualquier valor numérico.

Obligatorio si el campo es una fecha.

La unidad que se aplicará al campo de paso al incrementar los valores de fecha en el campo.

Puede especificar uno de los siguientes valores para unit como una cadena:

  • millisecond

  • second

  • minute

  • hour

  • day

  • week

  • month

  • quarter

  • year

Para ver un ejemplo, consulte Densificar datos de series de tiempo.

Para los documentos que contienen el campo especificado, errores$densify si:

  • Cualquier documento en la colección tiene un valor field de tipo fecha y el campo unit no está especificado.

  • Cualquier documento de la colección tiene un field valor de tipo numérico y se especifica el campo de unidad.

  • El field nombre empieza $ por. Debe renombrar el campo si desea densificarlo. Para renombrar los campos,$project utilice.

$densify errores si hay algún nombre de campo en la matriz partitionByFields:

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

  • Comienza con $.

Si range.bounds es una matriz:

  • El límite inferior indica el valor inicial para los documentos agregados, independientemente de los documentos que ya estén en la colección.

  • El límite inferior es inclusivo.

  • El límite superior es exclusivo.

  • $densify no filtra documentos con valores de campo fuera de los límites especificados.

$densify no garantiza el orden de clasificación de los documentos que genera.

Para garantizar el orden de clasificación,$sort utilice en el campo por el cual desea ordenar.

Cree una colección weather que contenga lecturas de temperatura en intervalos de cuatro horas.

db.weather.insertMany( [
{
"metadata": { "sensorId": 5578, "type": "temperature" },
"timestamp": ISODate("2021-05-18T00:00:00.000Z"),
"temp": 12
},
{
"metadata": { "sensorId": 5578, "type": "temperature" },
"timestamp": ISODate("2021-05-18T04:00:00.000Z"),
"temp": 11
},
{
"metadata": { "sensorId": 5578, "type": "temperature" },
"timestamp": ISODate("2021-05-18T08:00:00.000Z"),
"temp": 11
},
{
"metadata": { "sensorId": 5578, "type": "temperature" },
"timestamp": ISODate("2021-05-18T12:00:00.000Z"),
"temp": 12
}
] )

Este ejemplo utiliza la etapa $densify para completar los intervalos de cuatro horas y lograr una granularidad horaria en los puntos de datos:

db.weather.aggregate( [
{
$densify: {
field: "timestamp",
range: {
step: 1,
unit: "hour",
bounds:[ ISODate("2021-05-18T00:00:00.000Z"), ISODate("2021-05-18T08:00:00.000Z") ]
}
}
}
] )

En el ejemplo:

  • La etapa llena los espacios de tiempo entre las temperaturas $densify registradas.

    • field: "timestamp" densifica el campo timestamp.

  • range:

    • step: 1 incrementa el campo timestamp en 1 unidad.

    • unit: hour densifica el campo timestamp por hora.

    • bounds: [ ISODate("2021-05-18T00:00:00.000Z"), ISODate("2021-05-18T08:00:00.000Z") ] Establece el rango de tiempo que se densifica.

En la siguiente salida, la etapa rellena los espacios de tiempo entre las $densify horas 00:00:00 y.08:00:00

[
{
_id: ObjectId("618c207c63056cfad0ca4309"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T00:00:00.000Z"),
temp: 12
},
{ timestamp: ISODate("2021-05-18T01:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T02:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T03:00:00.000Z") },
{
_id: ObjectId("618c207c63056cfad0ca430a"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T04:00:00.000Z"),
temp: 11
},
{ timestamp: ISODate("2021-05-18T05:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T06:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T07:00:00.000Z") },
{
_id: ObjectId("618c207c63056cfad0ca430b"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T08:00:00.000Z"),
temp: 11
}
{
_id: ObjectId("618c207c63056cfad0ca430c"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T12:00:00.000Z"),
temp: 12
}
]

Cree una colección coffee que contenga datos de dos variedades de granos de café:

db.coffee.insertMany( [
{
"altitude": 600,
"variety": "Arabica Typica",
"score": 68.3
},
{
"altitude": 750,
"variety": "Arabica Typica",
"score": 69.5
},
{
"altitude": 950,
"variety": "Arabica Typica",
"score": 70.5
},
{
"altitude": 1250,
"variety": "Gesha",
"score": 88.15
},
{
"altitude": 1700,
"variety": "Gesha",
"score": 95.5,
"price": 1029
}
] )

Este ejemplo utiliza para densificar $densify el altitude campo para cada variety café:

db.coffee.aggregate( [
{
$densify: {
field: "altitude",
partitionByFields: [ "variety" ],
range: {
bounds: "full",
step: 200
}
}
}
] )

El ejemplo de agregación:

  • Particiona los documentos por variety para crear una agrupación para Arabica Typica y otra para Gesha café.

  • Especifica un full rango, lo que significa que los datos se densifican en todo el rango de documentos existentes para cada partición.

  • Especifica un step de 200, lo que significa que se crean nuevos documentos en intervalos de altitude de 200.

La agregación genera los siguientes documentos:

[
{
_id: ObjectId("618c031814fbe03334480475"),
altitude: 600,
variety: 'Arabica Typica',
score: 68.3
},
{
_id: ObjectId("618c031814fbe03334480476"),
altitude: 750,
variety: 'Arabica Typica',
score: 69.5
},
{ variety: 'Arabica Typica', altitude: 800 },
{
_id: ObjectId("618c031814fbe03334480477"),
altitude: 950,
variety: 'Arabica Typica',
score: 70.5
},
{ variety: 'Gesha', altitude: 600 },
{ variety: 'Gesha', altitude: 800 },
{ variety: 'Gesha', altitude: 1000 },
{ variety: 'Gesha', altitude: 1200 },
{
_id: ObjectId("618c031814fbe03334480478"),
altitude: 1250,
variety: 'Gesha',
score: 88.15
},
{ variety: 'Gesha', altitude: 1400 },
{ variety: 'Gesha', altitude: 1600 },
{
_id: ObjectId("618c031814fbe03334480479"),
altitude: 1700,
variety: 'Gesha',
score: 95.5,
price: 1029
},
{ variety: 'Arabica Typica', altitude: 1000 },
{ variety: 'Arabica Typica', altitude: 1200 },
{ variety: 'Arabica Typica', altitude: 1400 },
{ variety: 'Arabica Typica', altitude: 1600 }
]

Esta imagen visualiza los documentos creados $densify con:

Estado de la colección de café después de la densificación de rango completo
haga clic para ampliar
  • Los cuadrados más oscuros representan los documentos originales de la colección.

  • Los cuadrados más claros representan los documentos creados $densify con.

Este ejemplo utiliza solo para densificar los espacios en $densify el altitude campo dentro de variety cada:

db.coffee.aggregate( [
{
$densify: {
field: "altitude",
partitionByFields: [ "variety" ],
range: {
bounds: "partition",
step: 200
}
}
}
] )

El ejemplo de agregación:

  • Particiona los documentos por variety para crear una agrupación para Arabica Typica y otra para Gesha café.

  • Especifica un rango partition, lo que significa que los datos se densifican dentro de cada partición.

    • Para la partición Arabica Typica, el rango es 600-950.

    • Para la partición Gesha, el rango es 1250-1700.

  • Especifica un step de 200, lo que significa que se crean nuevos documentos en intervalos de altitude de 200.

La agregación genera los siguientes documentos:

[
{
_id: ObjectId("618c031814fbe03334480475"),
altitude: 600,
variety: 'Arabica Typica',
score: 68.3
},
{
_id: ObjectId("618c031814fbe03334480476"),
altitude: 750,
variety: 'Arabica Typica',
score: 69.5
},
{ variety: 'Arabica Typica', altitude: 800 },
{
_id: ObjectId("618c031814fbe03334480477"),
altitude: 950,
variety: 'Arabica Typica',
score: 70.5
},
{
_id: ObjectId("618c031814fbe03334480478"),
altitude: 1250,
variety: 'Gesha',
score: 88.15
},
{ variety: 'Gesha', altitude: 1450 },
{ variety: 'Gesha', altitude: 1650 },
{
_id: ObjectId("618c031814fbe03334480479"),
altitude: 1700,
variety: 'Gesha',
score: 95.5,
price: 1029
}
]

Esta imagen visualiza los documentos creados $densify con:

Estado de la colección de café después de la densificación del rango de partición
haga clic para ampliar
  • Los cuadrados más oscuros representan los documentos originales de la colección.

  • Los cuadrados más claros representan los documentos creados $densify con.

Los ejemplos de C# de esta página utilizan la sample_weatherdata.data colección de los conjuntos de datos de ejemplo de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de ejemplo, consulte la sección "Comenzar" en la documentación del controlador MongoDB.NET/C#.

Las siguientes clases Weather y Point modelan los documentos en la colección sample_weatherdata.data:

public class Weather
{
public Guid Id { get; set; }
public Point Position { get; set; }
[BsonElement("ts")]
public DateTime Timestamp { get; set; }
}
public class Point
{
public float[] Coordinates { get; set; }
}

La colección sample_weatherdata.data contiene los siguientes documentos, que contienen mediciones para el mismo campo position, con una hora de diferencia:

Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }}
Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}

Para usar el controlador MongoDB.NET/C# para agregar una $densify etapa a una canalización de agregación, llame a Densify()método en un PipelineDefinition objeto.

El siguiente ejemplo crea una etapa de canalización que añade un documento cada 15minutos entre los dos documentos anteriores. El código agrupa estos documentos según los valores de su campo Position.Coordinates.

var densifyTimeRange = new DensifyDateTimeRange(
new DensifyLowerUpperDateTimeBounds(
lowerBound: new DateTime(1984, 3, 5, 8, 0, 0),
upperBound: new DateTime(1984, 3, 5, 9, 0, 0)
),
step: 15,
unit: DensifyDateTimeUnit.Minutes
);
var pipeline = new EmptyPipelineDefinition<Weather>()
.Densify(
field: w => w.Timestamp,
range: densifyTimeRange,
partitionByFields: [w => w.Position.Coordinates]);

La etapa de agregación anterior genera los siguientes documentos destacados en la colección:

Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }}
Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:15:00 EST 1984 }}
Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:30:00 EST 1984 }}
Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:45:00 EST 1984 }}
Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}

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.

La colección sample_weatherdata.data contiene los siguientes documentos, que contienen mediciones para el mismo campo position, con una hora de diferencia:

{_id: new ObjectId(...), ts: 1984-03-05T13:00:00.000Z, position: {type: 'Point', coordinates: [-47.9, 47.6]}, ... },
{_id: new ObjectId(...), ts: 1984-03-05T14:00:00.000Z, position: {type: 'Point', coordinates: [-47.9, 47.6]}, ... }

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

El siguiente ejemplo crea una etapa de canalización que añade un documento cada 15minutos entre los dos documentos anteriores. El código agrupa estos documentos según los valores de su campo position.coordinates. El ejemplo ejecuta la canalización de agregación:

const pipeline = [
{
$densify: {
field: "ts",
partitionByFields: ["position.coordinates"],
range: {
step: 15,
unit: "minute",
bounds: [new Date(1984, 3, 5, 8, 0, 0), new Date(1984, 3, 5, 9, 0, 0)]
}
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

La etapa de agregación anterior genera los siguientes documentos destacados en la colección:

{ _id: new ObjectId(...), ts: 1984-03-05T13:00:00.000Z, position: {type: 'Point', coordinates: [-47.9, 47.6]}, ... },
{ position: { coordinates: [-47.9, 47.6] }, ts: 1984-03-05T13:15:00.000Z },
{ position: { coordinates: [-47.9, 47.6] }, ts: 1984-03-05T13:30:00.000Z },
{ position: { coordinates: [-47.9, 47.6] }, ts: 1984-03-05T13:45:00.000Z },
{ _id: new ObjectId(...), ts: 1984-03-05T14:00:00.000Z, position: {type: 'Point', coordinates: [-47.9, 47.6]}, ... }

Volver

$currentOp

En esta página