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.
Cree una vista materializada en la interfaz de usuario de MongoDB Atlas
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:
En la interfaz de usuario de MongoDB Atlas, vaya a Clusters Página para su proyecto.
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.
Si aún no se muestra, seleccione su proyecto en el menú Projects de la barra de navegación.
En la barra lateral, haz clic en Clusters en la sección Database.
La página de clústeres se muestra.
Seleccione una etapa de agregación en el menú desplegable Select
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:
Selecciona
$setdel menú desplegable Select.Añade la siguiente sintaxis al editor de pipeline de agregación para crear una puntuación media de todos los valores de
scoreen el arregloscoresdentro de la coleccióngrades:{ averageScore: { $avg: "$scores.score" } } MongoDB Atlas añade el valor
averageScorea cada documento.
Añadir la $out etapa
Seleccione la etapa
$outdel menú desplegable Select.Agrega la siguiente sintaxis a la canalización de agregación para guardar los resultados del pipeline en la colección
myViewen la base de datossample_training:'myView' 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.
Ejemplo
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") }, ] );
1. Define la vista materializada on-demand
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
$matchfiltra los datos para procesar solo aquellas ventas que son mayores o iguales astartDate.La etapa
$groupagrupa 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
$mergeguarda la salida en la colecciónmonthlybakesales.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:Cuando hay una coincidencia (es decir, ya existe un documento con el mismo año-mes en la colección), la etapa reemplaza el documento existente con el documento de los resultados de la agregación.
Cuando no hay coincidencia, la etapa inserta el documento de los resultados de la agregación en la colección (el comportamiento por defecto cuando no hay coincidencia).
2. Realizar la ejecución inicial
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") }
3. Refrescar la vista materializada
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") }
Información Adicional
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:
Más información sobre
$mergey las opciones disponiblesEjemplo: Vista materializada on-demand: actualizar/reemplazar datos
Ejemplo: Solo Insertar Nuevos Datos