Docs Menu
Docs Home
/ /

Vistas materializadas on-demand

Nota

Desambiguación

Esta página describe las vistas materializadas bajo demanda. Para obtener información sobre las vistas estándar, consulte Vistas.

Para comprender las diferencias entre los tipos de vista, consulte Comparación con vistas estándar.

Una vista materializada bajo demanda es un resultado de canalización de agregación precalculado que se almacena y se lee en el disco. Las vistas materializadas bajo demanda suelen ser el resultado de una $mergeEtapa $out o.

MongoDB ofrece dos tipos diferentes de vistas: vistas estándar y vistas materializadas on-demand. Ambos tipos de vistas devuelven los resultados de una canalización de agregación.

  • Las vistas estándar se calculan cuando lees la vista y no se almacenan en el disco.

  • Las vistas materializadas on-demand se almacenan y se leen desde el disco. Utilizan una etapa $merge o una $out para actualizar los datos guardados.

    Nota

    Al utilizar $merge, puede emplear flujos de cambios para monitorear los cambios en la vista materializada. Cuando utilice $out, no podrá observar los cambios en la vista materializada.

Las vistas estándar utilizan los índices de la colección subyacente. Como resultado, no puede crear, descartar ni reconstruir índices generales directamente en una vista estándar, ni obtener una lista de índices generales en la vista.

MongoDB almacena los índices de búsqueda y los índices de búsqueda vectoriales en disco. En consecuencia, se pueden crear índices de búsqueda de MongoDB e índices de búsqueda vectorial en vistas compatibles que contengan solo las siguientes etapas:

También puede crear índices directamente en las vistas materializadas on-demand, porque MongoDB almacena esos índices en el disco.

Las vistas materializadas on-demand ofrecen un mejor rendimiento de lectura que las vistas estándar porque se leen desde el disco en lugar de calcularse como parte de la query. Este beneficio en el rendimiento aumenta en función de la complejidad del pipeline y del tamaño de los datos que se están agregando.

El ejemplo en esta sección utiliza el conjunto de datos de entrenamiento de muestra. Para aprender a cargar el conjunto de datos de muestra en la implementación de MongoDB Atlas, se debe consultar Cargar datos de muestra.

Para crear una vista materializada en la Interfaz de Usuario de MongoDB Atlas, sigue estos pasos:

1
  1. Si aún no se muestra, seleccione la organización que contiene su proyecto deseado en el menú Organizations de la barra de navegación.

  2. Si aún no se muestra, seleccione su proyecto en el menú Projects de la barra de navegación.

  3. En la barra lateral, haz clic en Clusters en la sección Database.

    La página de clústeres se muestra.

2
  1. Para el clúster que contiene los datos de muestra, haz clic en Browse Collections.

  2. En el panel de navegación izquierdo, seleccione la base de datos sample_training.

  3. Seleccione la colección grades.

3
4
5

La etapa de agregación transforma los datos que deseas guardar como una vista. Para obtener más información sobre las etapas de agregación disponibles, consulta Etapas de agregación.

Para este ejemplo, añada un campo nuevo con la etapa $set:

  1. Selecciona $set del menú desplegable Select.

  2. Añade la siguiente sintaxis al editor de pipeline de agregación para crear una puntuación media de todos los valores de score en el arreglo scores dentro de la colección grades:

    {
    averageScore: { $avg: "$scores.score" }
    }

    MongoDB Atlas añade el valor averageScore a cada documento.

6
7
  1. Seleccione la etapa $out del menú desplegable Select.

  2. Agrega la siguiente sintaxis a la canalización de agregación para guardar los resultados del pipeline en la colección myView en la base de datos sample_training:

    'myView'
  3. Haga clic en Save Documents.

La etapa $out guarda los resultados de la canalización de agregación en la colección especificada, lo que crea la vista. Para obtener más información, consulta $out.

Actualice la lista de colecciones para ver la colección myView.

Para aprender a ejecutar un query sobre la colección de myView en la Interfaz de Usuario de MongoDB Atlas, consulta Ver, filtrar y ordenar documentos en la documentación de MongoDB Atlas.

Supón que a finales de enero de 2019, la colección bakesales contiene la información de ventas por artículos:

db.bakesales.insertMany( [
{ date: ISODate("2018-12-01"), item: "Cake - Chocolate", quantity: 2, amount: Decimal128("60") },
{ date: ISODate("2018-12-02"), item: "Cake - Peanut Butter", quantity: 5, amount: Decimal128("90") },
{ date: ISODate("2018-12-02"), item: "Cake - Red Velvet", quantity: 10, amount: Decimal128("200") },
{ date: ISODate("2018-12-04"), item: "Cookies - Chocolate Chip", quantity: 20, amount: Decimal128("80") },
{ date: ISODate("2018-12-04"), item: "Cake - Peanut Butter", quantity: 1, amount: Decimal128("16") },
{ date: ISODate("2018-12-05"), item: "Pie - Key Lime", quantity: 3, amount: Decimal128("60") },
{ date: ISODate("2019-01-25"), item: "Cake - Chocolate", quantity: 2, amount: Decimal128("60") },
{ date: ISODate("2019-01-25"), item: "Cake - Peanut Butter", quantity: 1, amount: Decimal128("16") },
{ date: ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") },
{ date: ISODate("2019-01-26"), item: "Cookies - Chocolate Chip", quantity: 12, amount: Decimal128("48") },
{ date: ISODate("2019-01-26"), item: "Cake - Carrot", quantity: 2, amount: Decimal128("36") },
{ date: ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") },
{ date: ISODate("2019-01-27"), item: "Pie - Chocolate Cream", quantity: 1, amount: Decimal128("20") },
{ date: ISODate("2019-01-27"), item: "Cake - Peanut Butter", quantity: 5, amount: Decimal128("80") },
{ date: ISODate("2019-01-27"), item: "Tarts - Apple", quantity: 3, amount: Decimal128("12") },
{ date: ISODate("2019-01-27"), item: "Cookies - Chocolate Chip", quantity: 12, amount: Decimal128("48") },
{ date: ISODate("2019-01-27"), item: "Cake - Carrot", quantity: 5, amount: Decimal128("36") },
{ date: ISODate("2019-01-27"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") },
{ date: ISODate("2019-01-28"), item: "Cookies - Chocolate Chip", quantity: 20, amount: Decimal128("80") },
{ date: ISODate("2019-01-28"), item: "Pie - Key Lime", quantity: 3, amount: Decimal128("60") },
{ date: ISODate("2019-01-28"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") },
] );

La siguiente función updateMonthlySales define una monthlybakesales vista materializada que contiene la información acumulada de ventas mensuales. En el ejemplo, la función toma un parámetro de fecha para actualizar únicamente la información de ventas mensuales a partir de una fecha específica.

updateMonthlySales = function(startDate) {
db.bakesales.aggregate( [
{ $match: { date: { $gte: startDate } } },
{ $group: { _id: { $dateToString: { format: "%Y-%m", date: "$date" } }, sales_quantity: { $sum: "$quantity"}, sales_amount: { $sum: "$amount" } } },
{ $merge: { into: "monthlybakesales", whenMatched: "replace" } }
] );
};
  • La etapa de $match filtra los datos para procesar solo aquellas ventas que son mayores o iguales a startDate.

  • La etapa $group agrupa la información de ventas por año-mes. Los documentos generados por esta etapa tienen el formato:

    { "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> }
  • La etapa $merge guarda la salida en la colección monthlybakesales.

    Basado en el campo _id (lo por defecto para las colecciones de salida no particionadas), la etapa verifica si el documento en los resultados de la agregación coincide con un documento existente en la colección:

Para la ejecución inicial, puedes pasar una fecha de new ISODate("1970-01-01"):

updateMonthlySales(new ISODate("1970-01-01"));

Después de la ejecución inicial, monthlybakesales contiene los siguientes documentos; es decir, db.monthlybakesales.find().sort( { _id: 1 } ) devuelve lo siguiente:

{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : Decimal128("506") }
{ "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : Decimal128("896") }

Supón que para la primera semana de febrero de 2019, la colección bakesales se actualiza con información de ventas más reciente; específicamente, ventas adicionales de enero y febrero.

db.bakesales.insertMany( [
{ date: ISODate("2019-01-28"), item: "Cake - Chocolate", quantity: 3, amount: Decimal128("90") },
{ date: ISODate("2019-01-28"), item: "Cake - Peanut Butter", quantity: 2, amount: Decimal128("32") },
{ date: ISODate("2019-01-30"), item: "Cake - Red Velvet", quantity: 1, amount: Decimal128("20") },
{ date: ISODate("2019-01-30"), item: "Cookies - Chocolate Chip", quantity: 6, amount: Decimal128("24") },
{ date: ISODate("2019-01-31"), item: "Pie - Key Lime", quantity: 2, amount: Decimal128("40") },
{ date: ISODate("2019-01-31"), item: "Pie - Banana Cream", quantity: 2, amount: Decimal128("40") },
{ date: ISODate("2019-02-01"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") },
{ date: ISODate("2019-02-01"), item: "Tarts - Apple", quantity: 2, amount: Decimal128("8") },
{ date: ISODate("2019-02-02"), item: "Cake - Chocolate", quantity: 2, amount: Decimal128("60") },
{ date: ISODate("2019-02-02"), item: "Cake - Peanut Butter", quantity: 1, amount: Decimal128("16") },
{ date: ISODate("2019-02-03"), item: "Cake - Red Velvet", quantity: 5, amount: Decimal128("100") }
] )

Para actualizar los datos de monthlybakesales de enero y febrero, ejecuta de nuevo la función para volver a ejecutar la canalización de agregación, comenzando por new ISODate("2019-01-01").

updateMonthlySales(new ISODate("2019-01-01"));

El contenido de monthlybakesales se ha actualizado para reflejar los datos más recientes en la colección bakesales; es decir, db.monthlybakesales.find().sort( { _id: 1 } ) devuelve lo siguiente:

{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : Decimal128("506") }
{ "_id" : "2019-01", "sales_quantity" : 102, "sales_amount" : Decimal128("1142") }
{ "_id" : "2019-02", "sales_quantity" : 15, "sales_amount" : Decimal128("284") }

La etapa $merge:

  • Se puede enviar a una colección en la misma base de datos o en una base de datos diferente.

  • Cree una nueva colección si la colección de salida no existe ya.

  • Puede incorporar resultados (insertar nuevos documentos, fusionar documentos, reemplazar documentos, mantener documentos existentes, fallar la operación, procesar documentos con un pipeline de actualización personalizado) en una colección existente.

  • Puede dar salida a una colección fragmentada. La colección de entrada también se puede fragmentar.

Consulta $merge para:

Volver

Operaciones compatibles

En esta página