Dados agregados no MongoDB Atlas - Funções
Nesta página
Visão geral
Os exemplos nesta página demonstram como usar a API de query do MongoDB em uma função para agregar documentos em seu Atlas cluster.
Ospipelines de agregação do MongoDB executam todos os documentos em uma coleção por meio de uma série de estágios de agregação de dados que permitem filtrar e moldar documentos, bem como coletar dados resumidos sobre grupos de documentos relacionados.
Observação
Estágios de aggregation suportados
O Atlas App Services é compatível com quase todos os aggregation pipeline stages e operadores do MongoDB, mas alguns estágios e operadores devem ser executados em uma função do sistema. Consulte Limitações de estrutura de aggregation para mais informações.
Modelo de dados
Os exemplos nesta página usam uma coleção chamada store.purchases
que contém informações sobre o histórico de vendas de itens em uma loja online. Cada documento contém uma lista dos items
adquiridos, incluindo o item name
e o quantity
comprado, bem como um valor de ID exclusivo para o cliente que comprou os itens.
{ "title": "Purchase", "required": ["_id", "customerId", "items"], "properties": { "_id": { "bsonType": "objectId" }, "customerId": { "bsonType": "objectId" }, "items": { "bsonType": "array", "items": { "bsonType": "object", "required": ["name", "quantity"], "properties": { "name": { "bsonType": "string" }, "quantity": { "bsonType": "int" } } } } } }
Configuração do trecho
Para usar um trecho de código em uma função, você deve primeiro instanciar um identificador de coleção do MongoDB:
exports = function() { const mongodb = context.services.get("mongodb-atlas"); const itemsCollection = mongodb.db("store").collection("items"); const purchasesCollection = mongodb.db("store").collection("purchases"); // ... paste snippet here ... }
Execute um Pipeline de Agregação
Você pode executar um aggregation pipeline utilizando o método collection.aggregate()
.
O trecho de trecho de função a seguir agrupa todos os documentos na purchases
coleção por seu customerId
valor de e agrega uma contagem do número de itens que cada cliente compra, bem como o número total de compras que ele fez. Após agrupar os documentos, o pipeline adiciona um novo campo que calcula o número médio de itens que cada cliente compra por vez, averageNumItemsPurchased
, ao documento de cada cliente:
const pipeline = [ { "$group": { "_id": "$customerId", "numPurchases": { "$sum": 1 }, "numItemsPurchased": { "$sum": { "$size": "$items" } } } }, { "$addFields": { "averageNumItemsPurchased": { "$divide": ["$numItemsPurchased", "$numPurchases"] } } } ] return purchasesCollection.aggregate(pipeline).toArray() .then(customers => { console.log(`Successfully grouped purchases for ${customers.length} customers.`) for(const customer of customers) { console.log(`customer: ${customer._id}`) console.log(`num purchases: ${customer.numPurchases}`) console.log(`total items purchased: ${customer.numItemsPurchased}`) console.log(`average items per purchase: ${customer.averageNumItemsPurchased}`) } return customers }) .catch(err => console.error(`Failed to group purchases by customer: ${err}`))
Localizar dados com o Atlas Search
Você pode executar queries do Atlas Search em uma collection com collection.aggregate()
e o estágio de aggregation $search
.
Importante
O App Services $search
executa as operações como um usuário do sistema e o
impõe regras de nível de campo nos resultados de pesquisa retornados. Isso significa que um
usuário pode pesquisar em um campo para o qual ele não tem acesso de leitura. Nesse caso, a pesquisa é baseada no campo especificado, mas nenhum documento retornado
inclui o campo.
exports = async function searchMoviesAboutBaseball() { // 1. Get a reference to the collection you want to search. const movies = context.services .get("mongodb-atlas") .db("sample_mflix") .collection("movies"); // 2. Run an aggregation with $search as the first stage. const baseballMovies = await movies .aggregate([ { $search: { text: { query: "baseball", path: "plot", }, }, }, { $limit: 5, }, { $project: { _id: 0, title: 1, plot: 1, }, }, ]) .toArray(); return baseballMovies; };
{ "plot" : "A trio of guys try and make up for missed opportunities in childhood by forming a three-player baseball team to compete against standard children baseball squads.", "title" : "The Benchwarmers" } { "plot" : "A young boy is bequeathed the ownership of a professional baseball team.", "title" : "Little Big League" } { "plot" : "A trained chimpanzee plays third base for a minor-league baseball team.", "title" : "Ed" } { "plot" : "The story of the life and career of the famed baseball player, Lou Gehrig.", "title" : "The Pride of the Yankees" } { "plot" : "Babe Ruth becomes a baseball legend but is unheroic to those who know him.", "title" : "The Babe" }
Observação
$$SEARCH_META disponibilidade variável
A variável de agregação $$SEARCH_META está disponível somente para funções que executam como sistema ou se o primeiro papel na coleção pesquisada tiver suas expressões apply_when
e read
configuradas para true
.
Se nenhum desses dois cenários se aplicar, $$SEARCH_META
será indefinido e a agregação falhará.
Estágios de aggregation
Filtrar documentos
Você pode usar o estágio $match para filtrar os documentos recebidos usando a sintaxe de consultapadrão do MongoDB.
{ "$match": { "<Field Name>": <Query Expression>, ... } }
Exemplo
O seguinte $match
estágio filtra os documentos recebidos para incluir
somente aqueles em que o graduation_year
campo tem um valor entre 2019
e 2024
, inclusive.
{ "$match": { "graduation_year": { "$gte": 2019, "$lte": 2024 }, } }
Documentos do grupo
Você pode utilizar o estágio $group para agregar dados de resumo para grupos de um ou mais documentos. O MongoDB agrupa documentos com base na expressão _id
.
Observação
Você pode referenciar um campo de documento específico prefixando o nome do campo com um $
.
{ "$group": { "_id": <Group By Expression>, "<Field Name>": <Aggregation Expression>, ... } }
Exemplo
O estágio $group
a seguir agrupa documentos pelo valor de seu campo customerId
e calcula o número de documentos de compra em que cada customerId
aparece.
{ "$group": { "_id": "$customerId", "numPurchases": { "$sum": 1 } } }
Campos do documento do projeto
Você pode usar o estágio $ projeto para incluir ou omitir campos específicos de documentos ou para calcular novos campos usando operadores de agregação. Para incluir um campo, defina seu valor para 1
. Para omitir um campo, defina seu valor para 0
.
Observação
Não é possível omitir e incluir campos que não sejam _id
simultaneamente. Se você incluir explicitamente um campo diferente de _id
, todos os campos que você não incluiu explicitamente serão automaticamente omitidos (e vice-versa).
{ "$project": { "<Field Name>": <0 | 1 | Expression>, ... } }
Exemplo
O estágio $project
a seguir omite o campo _id
, inclui o campo customerId
e cria um novo campo denominado numItems
onde o valor é o número de documentos na array items
:
{ "$project": { "_id": 0, "customerId": 1, "numItems": { "$sum": { "$size": "$items" } } } }
Adicionar campos aos documentos
Você pode usar o estágio $addFields para adicionar novos campos com valores calculados usando operadores de agregação.
Observação
$addFields
é semelhante ao $project, mas não permite que você inclua ou omita campos.
Exemplo
Os seguintes estágios $addFields
criam um novo campo chamado numItems
onde o valor é o número de documentos na array items
:
{ "$addFields": { "numItems": { "$sum": { "$size": "$items" } } } }
Unwind Array Values
Você pode utilizar o estágio $unwind para agregar elementos individuais de campos de array. Quando você desvincula um campo de array, o MongoDB copia cada documento uma vez para cada elemento do campo de array, mas substitui o valor de array pelo elemento de array em cada cópia.
{ $unwind: { path: <Array Field Path>, includeArrayIndex: <string>, preserveNullAndEmptyArrays: <boolean> } }
Exemplo
A etapa $unwind
a seguir cria um novo documento para cada elemento da array items
em cada documento. Ele também adiciona um campo chamado itemIndex
a cada novo documento que especifica o índice de posição do elemento na array original:
{ "$unwind": { "path": "$items", "includeArrayIndex": "itemIndex" } }
Considere o seguinte documento da coleção purchases
:
{ _id: 123, customerId: 24601, items: [ { name: "Baseball", quantity: 5 }, { name: "Baseball Mitt", quantity: 1 }, { name: "Baseball Bat", quantity: 1 }, ] }
Se aplicarmos o exemplo do estágio $unwind
a este documento, o estágio produzirá os três documentos a seguir:
{ _id: 123, customerId: 24601, itemIndex: 0, items: { name: "Baseball", quantity: 5 } }, { _id: 123, customerId: 24601, itemIndex: 1, items: { name: "Baseball Mitt", quantity: 1 } }, { _id: 123, customerId: 24601, itemIndex: 2, items: { name: "Baseball Bat", quantity: 1 } }