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.
Comparación con las vistas estándar
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
$mergeo una$outpara actualizar los datos guardados.
Indexes
Las vistas estándar utilizan los índices de la colección subyacente. Por lo tanto, no es posible crear, eliminar ni reconstruir índices directamente en una vista estándar, ni obtener una lista de índices en la vista.
Puede crear índices directamente en vistas materializadas a pedido porque se almacenan en el disco.
Rendimiento
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.
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 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:
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: 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") }, ] );
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" : Decimal128("506") } { "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : Decimal128("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: 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") }
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