Docs Menu
Docs Home
/ /
Bases de datos y colecciones

Vistas materializadas on-demand

Nota

En la página siguiente se describen las vistas materializadas bajo demanda. Para más información sobre las vistas, consulte Vistas en su lugar.

A partir de la versión 4.2, MongoDB agrega la $mergeEtapa para la canalización de agregación. Esta etapa permite fusionar los resultados de la canalización con una colección existente en lugar de reemplazarla por completo. Esta funcionalidad permite a los usuarios crear vistas materializadas bajo demanda, donde el contenido de la colección de salida se puede actualizar cada vez que se ejecuta la canalización.

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 desea guardar como vista. Para obtener más información sobre las etapas de agregación disponibles, consulte la Referencia rápida de la canalización 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: new ISODate("2018-12-01"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },
{ date: new ISODate("2018-12-02"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("90") },
{ date: new ISODate("2018-12-02"), item: "Cake - Red Velvet", quantity: 10, amount: new NumberDecimal("200") },
{ date: new ISODate("2018-12-04"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") },
{ date: new ISODate("2018-12-04"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },
{ date: new ISODate("2018-12-05"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") },
{ date: new ISODate("2019-01-25"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },
{ date: new ISODate("2019-01-25"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },
{ date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },
{ date: new ISODate("2019-01-26"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") },
{ date: new ISODate("2019-01-26"), item: "Cake - Carrot", quantity: 2, amount: new NumberDecimal("36") },
{ date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },
{ date: new ISODate("2019-01-27"), item: "Pie - Chocolate Cream", quantity: 1, amount: new NumberDecimal("20") },
{ date: new ISODate("2019-01-27"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("80") },
{ date: new ISODate("2019-01-27"), item: "Tarts - Apple", quantity: 3, amount: new NumberDecimal("12") },
{ date: new ISODate("2019-01-27"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") },
{ date: new ISODate("2019-01-27"), item: "Cake - Carrot", quantity: 5, amount: new NumberDecimal("36") },
{ date: new ISODate("2019-01-27"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },
{ date: new ISODate("2019-01-28"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") },
{ date: new ISODate("2019-01-28"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") },
{ date: new ISODate("2019-01-28"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("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" : NumberDecimal("506") }
{ "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : NumberDecimal("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: new ISODate("2019-01-28"), item: "Cake - Chocolate", quantity: 3, amount: new NumberDecimal("90") },
{ date: new ISODate("2019-01-28"), item: "Cake - Peanut Butter", quantity: 2, amount: new NumberDecimal("32") },
{ date: new ISODate("2019-01-30"), item: "Cake - Red Velvet", quantity: 1, amount: new NumberDecimal("20") },
{ date: new ISODate("2019-01-30"), item: "Cookies - Chocolate Chip", quantity: 6, amount: new NumberDecimal("24") },
{ date: new ISODate("2019-01-31"), item: "Pie - Key Lime", quantity: 2, amount: new NumberDecimal("40") },
{ date: new ISODate("2019-01-31"), item: "Pie - Banana Cream", quantity: 2, amount: new NumberDecimal("40") },
{ date: new ISODate("2019-02-01"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },
{ date: new ISODate("2019-02-01"), item: "Tarts - Apple", quantity: 2, amount: new NumberDecimal("8") },
{ date: new ISODate("2019-02-02"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },
{ date: new ISODate("2019-02-02"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },
{ date: new ISODate("2019-02-03"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("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" : NumberDecimal("506") }
{ "_id" : "2019-01", "sales_quantity" : 102, "sales_amount" : NumberDecimal("1142") }
{ "_id" : "2019-02", "sales_quantity" : 15, "sales_amount" : NumberDecimal("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

Vistas

En esta página