Visualizações materializadas sob demanda
Observação
A página a seguir discute visualizações materializadas on-demand. Para uma discussão sobre visualizações, consulte Visualizações .
A partir da versão 4.2, o MongoDB adiciona o estágio $merge
para o aggregation pipeline. This stage can merge the pipeline results to an existing collection instead of completely replacing the collection. Essa funcionalidade permite que os usuários criem exibições materializadas sob demanda, em que o conteúdo da collection de saída pode ser atualizado sempre que o pipeline é executado.
Crie uma visualização materializada na UI do MongoDB Atlas
O exemplo nesta seção utiliza o conjunto dedados de filmes de amostra do . Para saber como carregar o conjunto de dados de amostra em sua implantação do MongoDB Atlas, consulte Carregar Dados de Amostra.
Para criar uma visualização materializada na UI do MongoDB Atlas, siga estas etapas:
Na interface do usuário do MongoDB Atlas, vá para a Clusters página do seu projeto.
Se ainda não tiver sido exibido, selecione a organização que contém seu projeto no menu Organizations na barra de navegação.
Se ainda não estiver exibido, selecione seu projeto no menu Projects na barra de navegação.
Se ainda não estiver exibido, clique em Clusters na barra lateral.
A página Clusters é exibida.
Selecione um estágio de agregação no Select menu suspenso
O estágio de agregação transforma os dados que você deseja salvar em uma visualização. Para saber mais sobre os estágios de agregação disponíveis, consulte a Referência Rápida do Pipeline de Agregação.
Para este exemplo, adicione um novo campo com o estágio $set
:
Selecione
$set
no menu suspenso Select.Adicione a seguinte sintaxe ao editor do aggregation pipeline para criar uma pontuação média em todos os valores de
score
na arrayscores
dentro da coleçãogrades
:{ averageScore: { $avg: "$scores.score" } } O MongoDB Atlas adiciona o valor do
averageScore
a cada documento.
Adicione o $out
estágio
Selecione o estágio
$out
no menu suspenso Select.Adicione a seguinte sintaxe ao aggregation pipeline, para gravar os resultados do pipeline na coleção do
myView
no banco de dados dosample_training
:'myView' Clique em Save Documents.
O estágio $out
grava os resultados do pipeline de agregação na coleção especificada, que cria a visualização. Para saber mais, consulte $out
.
Atualize a lista de coleções para ver a collection myView
.
Para aprender como consultar a coleção do myView
na UI do MongoDB Atlas, consulte Visualizar, Filtrar e Classificar Documentos na documentação do MongoDB Atlas.
Exemplo
Suponha que, no final de janeiro de 2019, a coleta bakesales
contenha as informações de vendas por itens:
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. Definir a visão materializada on-demand
A função updateMonthlySales
a seguir define uma exibição materializada monthlybakesales
que contém as informações de vendas mensais cumulativas. No exemplo, a função usa um parâmetro de data para atualizar apenas as informações de vendas mensais a partir de uma data 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" } } ] ); };
O estágio
$match
filtra os dados para processar somente as vendas maiores ou iguais astartDate
.A etapa
$group
agrupa as informações de vendas por ano-mês. Os documentos gerados por esse estágio têm o formato:{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> } O estágio
$merge
escreve o resultado na collectionmonthlybakesales
.Com base no campo
_id
(o padrão para coleções de saída não fragmentadas), o estágio verifica se o documento nos resultados da agregação corresponde a um documento existente na coleção:Quando há uma correspondência (ou seja, um documento com o mesmo ano-mês já existe na coleção), o estágio substitui o documento existente pelo documento dos resultados da agregação.
Quando não há uma correspondência, o estágio insere o documento dos resultados da agregação na coleção (o comportamento padrão quando não correspondido).
2. Realizar execução inicial
Para a execução inicial, é possível passar uma data de new
ISODate("1970-01-01")
:
updateMonthlySales(new ISODate("1970-01-01"));
Após a execução inicial, o monthlybakesales
contém os seguintes documentos, ou seja, o db.monthlybakesales.find().sort( { _id: 1 } )
retorna o seguinte:
{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : NumberDecimal("506") } { "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : NumberDecimal("896") }
3. Atualizar visualização materializada
Suponha que, na primeira semana de fevereiro de 2019, a collection bakesales
seja atualizada com informações de vendas mais recentes; especificamente, vendas adicionais de janeiro e fevereiro.
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 atualizar os dados do monthlybakesales
de janeiro e fevereiro, execute novamente a função para executar novamente o aggregation pipeline, começando com new ISODate("2019-01-01")
.
updateMonthlySales(new ISODate("2019-01-01"));
O conteúdo de monthlybakesales
foi atualizado para refletir os dados mais recentes na coleta bakesales
; isto é, db.monthlybakesales.find().sort( { _id: 1 } )
retorna o seguinte:
{ "_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") }
Informações adicionais
O estágio $merge
:
Pode enviar para uma coleção no mesmo banco de dados ou em um banco de dados diferente.
Cria uma nova coleta se a coleta de saída ainda não existir.
Pode incorporar resultados (inserir novos documentos, mesclar documentos, substituir documentos, manter documentos existentes, falhar a operação, processar documentos com um pipeline de atualização personalizado) a uma coleção existente.
Pode gerar saída para uma coleção fragmentada. A coleta de entrada também pode ser fragmentada.
Consulte $merge
para:
Mais informações sobre
$merge
e opções disponíveisExemplo: Visualização materializada sob demanda: criação inicial
Exemplo: Visualização materializada sob demanda: atualizar/substituir dados
Exemplo: inserir apenas novos dados