Como executar pesquisa de query no Atlas Search do utilizando visualizações materializadas
Nesta página
Este tutorial descreve como criar um índice e executar queries na coleção sample_supplies.sales
do a partir do conjunto de dados de amostra e um novo sample_supplies.purchaseOrders
.
A visualização materializada sob demanda é uma coleção que você cria e atualiza utilizando uma fase do pipeline de agregação $merge
. Você pode criar um índice do Atlas Search na visualização materializada e, em seguida, executar queries na visualização materializada utilizando a fase do pipeline de agregação $search
.
Este tutorial orienta você pelas seguintes etapas:
Criar uma coleção denominada
purchaseOrders
no banco de dadossample_supplies
.Crie dois triggers agendados:
updateMonthlySales
, com uma função chamadaupdateMonthlySales
que inicializa a visualização materializadamonthlyPhoneTransactions
usando dados da coleçãosample_supplies.sales
de amostra.updateMonthlyPurchaseOrders
, com uma função chamadaupdateMonthlyPurchaseOrders
que atualiza a visualização materializadamonthlyPhoneTransactions
usando dados da coleçãosample_supplies.purchaseOrders
.
Crie um índice do Atlas Search na visualização materializada
monthlyPhoneTransactions
.Execute uma query na
monthlyPhoneTransactions
visualização materializada.
Antes de começar, certifique-se de que seu Atlas cluster atenda aos requisitos descritos nos Pré-requisitos.
Para criar um índice do Atlas Search, você deve ter acesso do Project Data Access Admin
ou superior ao projeto.
Para criar os triggers, você deve ter o acesso Project Owner
ou superior ao projeto.
Crie a coleção purchaseOrders
Conecte-se ao banco de dados sample_supplies
.
Abra o
mongosh
em uma janela do terminal e conecte-se ao seu cluster. Para obter instruções detalhadas sobre a conexão, consulte Conectar viamongosh
.Use o banco de dados
sample_supplies
:use sample_supplies
Adicionar uma nova coleção.
Adicione a coleção purchaseOrders
com novos dados de ordem de compra por telefone de janeiro de 2018. Execute os seguintes comandos:
db.purchaseOrders.insertMany( [ { saleDate: ISODate("2018-01-23T21:06:49.506Z"), items: [ { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("40.01"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("35.29"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("56.12"), quantity: 5 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("77.71"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("18.47"), quantity: 2 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("19.95"), quantity: 8 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.08"), quantity: 3 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("14.16"), quantity: 3 } ], storeLocation: 'Denver', customer: { gender: 'M', age: 42, email: 'cauho@witwuta.sv', satisfaction: 4 }, couponUsed: true, purchaseMethod: 'Phone' } ])
db.purchaseOrders.insertMany( [ { saleDate: ISODate("2018-01-25T10:01:02.918Z"), items: [ { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.05"), quantity: 10 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("28.31"), quantity: 9 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("20.95"), quantity: 3 }, { name: 'laptop', tags: [ 'electronics', 'school', 'office' ], price: Decimal128("866.5"), quantity: 4 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("33.09"), quantity: 4 }, { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("37.55"), quantity: 1 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("83.28"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("42.9"), quantity: 4 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("16.68"), quantity: 2 } ], storeLocation: 'Seattle', customer: { gender: 'M', age: 50, email: 'keecade@hem.uy', satisfaction: 5 }, couponUsed: false, purchaseMethod: 'Phone' } ])
Fazer query na nova coleção.
Query a coleção purchaseOrders
para confirmar as novas entradas de ordem de compra.
db.purchaseOrders.find().sort( {saleDate: -1} )
{ _id: ObjectId("62434c07d574cd0ce200ba75"), saleDate: ISODate("2018-01-25T10:01:02.918Z"), items: [ { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.05"), quantity: 10 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("28.31"), quantity: 9 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("20.95"), quantity: 3 }, { name: 'laptop', tags: [ 'electronics', 'school', 'office' ], price: Decimal128("866.5"), quantity: 4 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("33.09"), quantity: 4 }, { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("37.55"), quantity: 1 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("83.28"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("42.9"), quantity: 4 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("16.68"), quantity: 2 } ], storeLocation: 'Seattle', customer: { gender: 'M', age: 50, email: 'keecade@hem.uy', satisfaction: 5 }, couponUsed: false, purchaseMethod: 'Phone' }, { _id: ObjectId("62434c07d574cd0ce200ba74"), saleDate: ISODate("2018-01-23T21:06:49.506Z"), items: [ { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("40.01"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("35.29"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("56.12"), quantity: 5 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("77.71"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("18.47"), quantity: 2 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("19.95"), quantity: 8 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.08"), quantity: 3 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("14.16"), quantity: 3 } ], storeLocation: 'Denver', customer: { gender: 'M', age: 42, email: 'cauho@witwuta.sv', satisfaction: 4 }, couponUsed: true, purchaseMethod: 'Phone' }
Os dois resultados da consulta refletem que os dados da ordem de compra terminam em janeiro de 2018.
Criar os Triggers Agendados
Nos procedimentos a seguir, você cria triggers para criar uma visualização materializada e agendar uma função para atualizar a visualização materializada diariamente.
Crie o trigger updateMonthlySales
Procedimento
No Atlas, VáGo para a Triggers 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.
Na barra lateral, clique em Triggers sob o título Services.
A página Acionadores é exibida.
Inserir valores de configuração para o trigger.
Nome do campo UI | Configuração |
---|---|
Trigger Type | Selecione Scheduled. |
Name | Especifique |
Schedule Type |
|
Select An Event Type | Selecione Function. |
Crie a função.
A função para este trigger define uma visualização materializada monthlyPhoneTransactions
que contém informações de vendas mensais cumulativas. A função atualiza as informações de vendas mensais para vendas realizadas por telefone.
Cole o seguinte código na função:
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("sales"); return monthlyPhoneTransactions.aggregate(pipeline); };
A função utiliza os seguintes estágios do aggregation pipeline para atualizar monthlyPhoneTransactions
:
O estágio
$match
filtra os dados para processar somente as vendas que foram concluídas noPhone
.A etapa
$group
agrupa as informações de vendas por ano-mês. Esta etapa gera documentos do formulário:{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> } O estágio
$set
altera o tipo de dados do camposales_price
paradouble
. Os operadores$search
do Atlas Search não são compatíveis com o tipo de dadosDecimal128
. Alterar o tipo de dados do camposales_price
permite fazer query deste campo utilizando índices de pesquisa do Atlas Search.O estágio
$merge
grava a saída na coleçãomonthlyPhoneTransactions
.Com base no campo
_id
, o estágio verifica se o documento nos resultados de agregação corresponde a um documento existente na coleção:Quando o Atlas Search encontra uma correspondência (ou seja, um documento com o mesmo ano-mês já existe na coleção), o Atlas Search substitui o documento existente pelo documento dos resultados da agregação, conforme especificado no estágio.
Quando o Atlas Search não encontra uma correspondência, o Atlas Search insere o documento dos resultados da agregação na coleção conforme especificado no estágio.
Crie o trigger updateMonthlyPurchaseOrders
Procedimento
No Atlas, váGo para a Triggers 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.
Na barra lateral, clique em Triggers sob o título Services.
A página Acionadores é exibida.
Inserir valores de configuração para o trigger.
Nome do campo UI | Configuração |
---|---|
Trigger Type | Selecione Scheduled. |
Name | Especifique |
Schedule Type |
|
Crie a função.
Como a função updateMonthlyPurchaseOrders
opera
A função updateMonthlyPurchaseOrders
adiciona informações mensais cumulativas da ordem de compra à visualização materializada monthlyPhoneTransactions
. A função atualiza as informações mensais dos pedidos de compras realizados por telefone. O exemplo abaixo define a função:
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("purchaseOrders"); return monthlyPhoneTransactions.aggregate(pipeline); };
A função updateMonthlyPurchaseOrders
usa as mesmas fases do pipeline de agregação para atualizar monthlyPhoneTransactions
que a função updateMonthlySales
.
Teste a função.
Clique no botão Run no canto inferior direito do Function Editor para atualizar a visualização materializada de monthlyPhoneTransactions
.
A guia Result na parte inferior do Function Editor reflete o status de execução da função.
A função updateMonthlyPurchaseOrders
atualiza a exibição materializada monthlyPhoneTransactions
com os dados da ordem de compra de janeiro de 2018.
Use mongosh
para consultar a coleção monthlyPhoneTransactions
para confirmar a atualização:
db.monthlyPhoneTransactions.find().sort( { _id: -1} )
{ _id: '2018-01', sales_quantity: 66, sales_price: Decimal128("1407.10") }
A visualização materializada monthlyPhoneTransactions
mostra os dados recém-adicionados. O resultado principal indica que a transação mais recente ocorreu em janeiro de 2018.
Criar um índice do Atlas Search na visualização materializada
Crie um índice do Atlas Search na collection monthlyPhoneTransactions
.
No Atlas, váGo 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 o projeto desejado 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.
Acesse a página do Atlas Search do seu cluster.
Você pode acessar a página do Atlas Search pela barra lateral, pelo Data Explorer ou pela página de detalhes do cluster.
Na barra lateral, clique em Atlas Search sob o título Services.
No menu suspenso Select data source, selecione seu cluster e clique em Go to Atlas Search.
A página Atlas Search é exibida.
Clique no botão Browse Collections para o seu cluster.
Expanda o banco de dados e selecione a coleção.
Clique na guia Search Indexes da coleção.
A página Atlas Search é exibida.
Clique no nome do seu cluster.
Clique na aba Atlas Search.
A página Atlas Search é exibida.
Verifique o status.
O índice recém-criado aparece na aba Atlas Search. Enquanto o índice está construindo, o campo Status lê Building. Quando o índice terminar de construir, o campo Status lê Active.
Observação
Collections maiores demoram mais tempo para indexar. Você receberá uma notificação por e-mail quando seu índice terminar a criação.
Executar uma query na visualização materializada
Execute uma query na coleção monthlyPhoneTransactions
recém-atualizada e indexada.
Conecte-se ao seu cluster no mongosh
.
Abra o mongosh
em uma janela do terminal e conecte ao seu cluster. Para obter instruções detalhadas sobre a conexão, consulte Conectar via mongosh
.
Use o banco de dados sample_supplies
.
Execute o seguinte comando no prompt mongosh
:
use sample_supplies
Execute uma query simples do Atlas Search na coleção sample_supplies.monthlyPhoneTransactions
.
A query a seguir conta o número de meses em monthlyPhoneTransactions com vendas totais maiores ou iguais a 10000
dólares:
db.monthlyPhoneTransactions.aggregate([ { $search: { "index": "monthlySalesIndex", "range": { "gt": 10000, "path": ["sales_price"] } } }, { $count: 'months_w_over_10000' }, ])
A query acima retorna 4
, indicando que apenas 4 meses de todos os meses na visualização materializada monthlyPhoneTransactions
tiveram vendas totais maiores ou iguais a 10000 dólares. Este resultado reflete dados das coleções sample_supplies.sales
e sample_supplies.purchaseOrders
.
Para obter a documentação completa do pipeline de agregação, consulte o Manual do MongoDB Server.