Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

$ acumulador ( operador acumulador )

$accumulator

Importante

JavaScript do lado do servidor obsoleto

A partir do MongoDB,8.0 as funções JavaScript do lado do servidor$accumulator $function(,, $where) estão obsoletas. O MongoDB registra um aviso quando você executa essas funções.

Defines a custom accumulator operator. Accumulators are operators that maintain their state (e.g. totals, maximums, minimums, and related data) as documents progress through the pipeline. Use the $accumulator operator to execute your own JavaScript functions to implement behavior not supported by the MongoDB Query Language. See also $function.

$accumulator está disponível nestes estágios:

Importante

Executing JavaScript inside of an aggregation operator may decrease performance. Only use the $accumulator operator if the provided pipeline operators cannot fulfill your application's needs.

The $accumulator operator has this syntax:

{
$accumulator: {
init: <code>,
initArgs: <array expression>, // Optional
accumulate: <code>,
accumulateArgs: <array expression>,
merge: <code>,
finalize: <code>, // Optional
lang: <string>
}
}
Campo
Tipo
Descrição

String ou código

Função usada para inicializar o estado. A função init recebe seus argumentos da expressão de array initArgs. Você pode especificar a definição da função como tipos de BSON ou String do tipo BSON.

A função init tem a seguinte forma:

function (<initArg1>, <initArg2>, ...) {
...
return <initialState>
}

O derramamento no disco ou a execução de uma query em um cluster fragmentado pode fazer com que o acumulador seja computado como uma mescla de vários subacumuladores, cada um dos quais começa chamando init(). Certifique-se de que suas funções init(), accumulate() e merge() sejam compatíveis com este modelo de execução.

Array

Opcional. Argumentos passados para a função init.

initArgs tem o seguinte formato:

[ <initArg1>, <initArg2>, ... ]

IMPORTANTE: Quando usado em um estágio $bucketAuto, initArgs não pode referir-se à chave do grupo (ou seja, você não pode usar a sintaxe $<fieldName>). Em vez disso, em um estágio do $bucketAuto, você pode somente especificar valores constantes no initArgs.

String ou código

Function used to accumulate documents. The accumulate function receives its arguments from the current state and accumulateArgs array expression. The result of the accumulate function becomes the new state. You can specify the function definition as either BSON type Code or String.

A função accumulate tem a seguinte forma:

function(state, <accumArg1>, <accumArg2>, ...) {
...
return <newState>
}

Array

Argumentos passados para a função accumulate . Você pode usar accumulateArgs para especificar quais valores de campo passar para a função accumulate .

accumulateArgs tem o seguinte formato:

[ <accumArg1>, <accumArg2>, ... ]

String ou código

Function used to merge two internal states. merge must be either a String or Code BSON type. merge returns the combined result of the two merged states. For information on when the merge function is called, see Merge Two States with $merge.

A função merge tem a seguinte forma:

function (<state1>, <state2>) {
<logic to merge state1 and state2>
return <newState>
}

String ou código

Opcional. Função usada para atualizar o resultado do acúmulo.

A função finalize tem a seguinte forma:

function (state) {
...
return <finalState>
}

String

The language used in the $accumulator code.

IMPORTANTE: Atualmente, o único valor suportado para lang é js.

The following steps outline how the $accumulator operator processes documents:

  1. O operador começa em um estado inicial, definido pela função init.

  2. Para cada documento, o operador atualiza o estado com base na função accumulate . O primeiro argumento da função acumular é o estado atual, e argumentos adicionais são especificados na array accumulateArgs.

  3. When the operator needs to merge multiple intermediate states, it executes the merge function. For more information on when the merge function is called, see Merge Two States with $merge.

  4. Se uma função finalizar tiver sido definida, uma vez que todos os documentos tenham sido processados e o estado tenha sido atualizado de acordo, finalizar converte o estado em uma saída final.

As part of its internal operations, the $accumulator operator may need to merge two separate, intermediate states. The merge function specifies how the operator should merge two states.

A função de mesclagem sempre mescla dois estados de cada vez. No evento de mais de dois estados precisarem ser mesclados, a fusão resultante de dois estados é mesclada com um único estado. Esse processo se repete até que todos os estados sejam mesclados.

For example, $accumulator may need to combine two states in the following scenarios:

  • $accumulator é executado em um cluster fragmentado. O operador precisa mesclar os resultados de cada fragmento para obter o resultado final.

  • A single $accumulator operation exceeds its specified memory limit. If you specify the allowDiskUse option, the operator stores the in-progress operation on disk and finishes the operation in memory. Once the operation finishes, the results from disk and memory are merged together using the merge function.

A ordem em que o MongoDB processa documentos para as funções init(), accumulate() e merge() pode variar e ser diferente da ordem em que esses documentos são especificados para a função $accumulator.

Por exemplo, considere uma série de documentos em que os campos _id são as letras do alfabeto:

{ _id: 'a' },
{ _id: 'b' },
{ _id: 'c' }
...
{ _id: 'z' }

Em seguida, considere um pipeline de agregação que classifica os documentos pelo campo _id e usa uma função $accumulator para concatenar os valores do campo _id:

[
{
$sort: { _id: 1 }
},
{
$group: {
_id: null,
alphabet: {
$accumulator: {
init: function() {
return ""
},
accumulate: function(state, letter) {
return(state + letter)
},
accumulateArgs: [ "$_id" ],
merge: function(state1, state2) {
return(state1 + state2)
},
lang: "js"
}
}
}
}
]

O MongoDB não garante que os documentos sejam processados na ordem de classificação, o que significa que o campo alphabet não é necessariamente definido como abc...z.

Devido a esse comportamento, garanta que sua função $accumulator não precise processar e retornar documentos em uma ordem específica.

To use $accumulator, you must have server-side scripting enabled.

If you do not use $accumulator (or $function, $where, or mapReduce), disable server-side scripting:

Consulte também ➤ Executar o MongoDB com opções de configuração seguras.

O MongoDB atualiza o 6.0 mecanismo JavaScript interno usado para expressões JavaScript,, e do lado$accumulator do$function $where servidor e do MozJS- para60 o91 MozJS-. Várias funções de array e string de caracteres não padrão obsoletas que existiam no MozJS-60 são removidas no91 MozJS-.

Observação

This example walks through using the $accumulator operator to implement the $avg operator, which is already supported by MongoDB. The goal of this example is not to implement new functionality, but to illustrate the behavior and syntax of the $accumulator operator with familiar logic.

In mongosh, create a sample collection named books with the following documents:

db.books.insertMany([
{ _id: 8751, title: "The Banquet", author: "Dante", copies: 2 },
{ _id: 8752, title: "Divine Comedy", author: "Dante", copies: 1 },
{ _id: 8645, title: "Eclogues", author: "Dante", copies: 2 },
{ _id: 7000, title: "The Odyssey", author: "Homer", copies: 10 },
{ _id: 7020, title: "Iliad", author: "Homer", copies: 10 }
])

The following operation groups the documents by author, and uses $accumulator to compute the average number of copies across books for each author:

db.books.aggregate([
{
$group :
{
_id : "$author",
avgCopies:
{
$accumulator:
{
init: function() { // Set the initial state
return { count: 0, sum: 0 }
},
accumulate: function(state, numCopies) { // Define how to update the state
return {
count: state.count + 1,
sum: state.sum + numCopies
}
},
accumulateArgs: ["$copies"], // Argument required by the accumulate function
merge: function(state1, state2) { // When the operator performs a merge,
return { // add the fields from the two states
count: state1.count + state2.count,
sum: state1.sum + state2.sum
}
},
finalize: function(state) { // After collecting the results from all documents,
return (state.sum / state.count) // calculate the average
},
lang: "js"
}
}
}
}
])

Esta operação retorna o seguinte resultado:

{ _id: "Dante", avgCopies: 1.6666666666666667 }
{ _id: "Homer", avgCopies: 10 }

The $accumulator defines an initial state where count and sum are both set to 0. For each document that the $accumulator processes, it updates the state by:

  • Incrementando o count por 1 e

  • Adding the values of the document's copies field to the sum. The accumulate function can access the copies field because it is passed in the accumulateArgs field.

Com cada documento processado, a função de acumulação retorna o estado atualizado.

Once all documents have been processed, the finalize function divides the sum of the copies by the count of documents to obtain the average. This removes the need to keep a running computed average, since the finalize function receives the cumulative sum and count of all documents.

Esta operação é equivalente à seguinte pipeline, que utiliza o operador $avg:

db.books.aggregate([
{
$group : {
_id : "$author",
avgCopies: { $avg: "$copies" }
}
}
])

You can use the initArgs option in to vary the initial state of $accumulator. This can be useful if you want to, for example:

  • Usar o valor de um campo que não está em seu estado para afetar seu estado, ou

  • Definir o estado inicial para um valor diferente com base no grupo que está sendo processado.

In mongosh, create a sample collection named restaurants with the following documents:

db.restaurants.insertMany( [
{ _id: 1, name: "Food Fury", city: "Bettles", cuisine: "American" },
{ _id: 2, name: "Meal Macro", city: "Bettles", cuisine: "Chinese" },
{ _id: 3, name: "Big Crisp", city: "Bettles", cuisine: "Latin" },
{ _id: 4, name: "The Wrap", city: "Onida", cuisine: "American" },
{ _id: 5, name: "Spice Attack", city: "Onida", cuisine: "Latin" },
{ _id: 6, name: "Soup City", city: "Onida", cuisine: "Chinese" },
{ _id: 7, name: "Crave", city: "Pyote", cuisine: "American" },
{ _id: 8, name: "The Gala", city: "Pyote", cuisine: "Chinese" }
] )

Supor que um aplicativo permita que os usuários consultem esses dados para encontrar restaurantes. Pode ser útil mostrar mais resultados para a cidade onde o usuário vive. Para este exemplo, assumimos que a cidade do usuário é chamada em uma variável chamada userProfileCity.

The following aggregation pipeline groups the documents by city. The operation uses the $accumulator to display a different number of results from each city depending on whether the restaurant's city matches the city in the user's profile:

Observação

To execute this example in mongosh, replace <userProfileCity> in the initArgs with a string containing an actual city value, such as Bettles.

1db.restaurants.aggregate([
2{
3 $group :
4 {
5 _id : { city: "$city" },
6 restaurants:
7 {
8 $accumulator:
9 {
10 init: function(city, userProfileCity) { // Set the initial state
11 return {
12 max: city === userProfileCity ? 3 : 1, // If the group matches the user's city, return 3 restaurants
13 restaurants: [] // else, return 1 restaurant
14 }
15 },
16
17 initArgs: ["$city", <userProfileCity>], // Argument to pass to the init function
18
19 accumulate: function(state, restaurantName) { // Define how to update the state
20 if (state.restaurants.length < state.max) {
21 state.restaurants.push(restaurantName);
22 }
23 return state;
24 },
25
26 accumulateArgs: ["$name"], // Argument required by the accumulate function
27
28 merge: function(state1, state2) {
29 return {
30 max: state1.max,
31 restaurants: state1.restaurants.concat(state2.restaurants).slice(0, state1.max)
32 }
33 },
34
35 finalize: function(state) { // Adjust the state to only return field we need
36 return state.restaurants
37 }
38
39 lang: "js"
40 }
41 }
42 }
43}
44])

Se o valor de userProfileCity for Bettles, esta operação retornará o seguinte resultado:

{ _id: { city: "Bettles" }, restaurants: { restaurants: [ "Food Fury", "Meal Macro", "Big Crisp" ] } }
{ _id: { city: "Onida" }, restaurants: { restaurants: [ "The Wrap" ] } }
{ _id: { city: "Pyote" }, restaurants: { restaurants: [ "Crave" ] } }

Se o valor de userProfileCity for Onida, esta operação retornará o seguinte resultado:

{ _id: { city: "Bettles" }, restaurants: { restaurants: [ "Food Fury" ] } }
{ _id: { city: "Onida" }, restaurants: { restaurants: [ "The Wrap", "Spice Attack", "Soup City" ] } }
{ _id: { city: "Pyote" }, restaurants: { restaurants: [ "Crave" ] } }

Se o valor de userProfileCity for Pyote, esta operação retornará o seguinte resultado:

{ _id: { city: "Bettles" }, restaurants: { restaurants: [ "Food Fury" ] } }
{ _id: { city: "Onida" }, restaurants: { restaurants: [ "The Wrap" ] } }
{ _id: { city: "Pyote" }, restaurants: { restaurants: [ "Crave", "The Gala" ] } }

Se o valor de userProfileCity for qualquer outro valor, esta operação retornará o seguinte resultado:

{ _id: { city: "Bettles" }, restaurants: { restaurants: [ "Food Fury" ] } }
{ _id: { city: "Onida" }, restaurants: { restaurants: [ "The Wrap" ] } }
{ _id: { city: "Pyote" }, restaurants: { restaurants: [ "Crave" ] } }

A função init define um estado inicial que contém max os restaurants campos e. O max campo define o número máximo de restaurantes para este grupo em particular. Se o city campo do documento corresponder userProfileCity a, esse grupo conterá um máximo de 3 restaurantes. Caso contrário, se o documento _id não corresponder userProfileCity a, o grupo conterá no máximo um único restaurante. A função init recebe os city userProfileCity argumentos argumentos da arrayinitArgs.

For each document that the $accumulator processes, it pushes the name of the restaurant to the restaurants array, provided that name would not put the length of restaurants over the max value. With each document that is processed, the accumulate function returns the updated state.

The merge function defines how to merge two states. The function concatenates the restaurant arrays from each state together, and the length of the resulting array is limited using the slice() method to ensure that it does not exceed the max value.

Once all documents have been processed, the finalize function modifies the resulting state to only return the names of the restaurants. Without this function, the max field would also be included in the output, which does not fulfill any needs for the application.