On this page本页内容
$accumulator
¶New in version 4.4.版本4.4中的新功能。
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.使用$accumulator
运算符执行自己的JavaScript函数,以实现MongoDB查询语言不支持的行为。See also $function.另请参见$function。
Important
Executing JavaScript inside of an aggregation operator may decrease performance.在聚合运算符中执行JavaScript可能会降低性能。Only use the $accumulator operator if the provided pipeline operators cannot fulfill your application’s needs.仅当提供的管道运算符无法满足应用程序的需要时,才使用$accumulator
运算符。
$accumulator is available in the following pipeline stages:$accumulator
可在以下管道阶段使用:
The $accumulator operator has the following syntax:$accumulator
运算符语法如下所示:
init |
|
|
initArgs | Array |
Important
|
accumulate | String or Code |
|
accumulateArgs | Array |
|
merge |
|
|
finalize |
|
|
lang | String |
Important
|
The following steps outline how the $accumulator operator processes documents:以下步骤概述了$accumulator运算符如何处理文档:
accumulate
函数更新状态。accumulate
函数的第一个参数是当前状态,其他参数可以在accumulateArgs数组中指定。merge
函数。merge
函数的更多信息,请参阅使用$merge
合并两个状态。$merge
$merge
合并两个州¶As part of its internal operations, the $accumulator operator may need to merge two separate, intermediate states.作为内部操作的一部分,$accumulator
运算符可能需要合并两个独立的中间状态。The merge function specifies how the operator should merge two states.merge
函数指定运算符应该如何合并两个状态。
For example, $accumulator may need to combine two states when:例如,在以下情况下,$accumulator
可能需要组合两种状态:
$accumulator
在分片集群上运行。$accumulator
操作超过其指定的内存限制。allowDiskUse
选项,运算符会将正在进行的操作存储在磁盘上,并在内存中完成该操作。See also参阅
To use 要使用$accumulator
, you must have server-side scripting enabled.$accumulator
,必须启用服务器端脚本。
If you do not use $accumulator (or $function, $where, or mapReduce), disable server-side scripting:如果不使用$accumulator
(或$function
、$where
或mapReduce
),请禁用服务器端脚本:
mongod
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。mongos
实例,请参阅security.javascriptEnabled
配置选项或从MongoDB 4.4开始的--noscripting
命令行选项。
mongos
实例上执行JavaScript。See also 另请参阅➤ Run MongoDB with Secure Configuration Options使用安全配置选项运行MongoDB.
$accumulator
to Implement the $avg
Operator$accumulator
实现$avg
运算符¶Note
This example walks through using the $accumulator operator to implement the $avg operator, which is already supported by MongoDB. 本例介绍如何使用$accumulator
运算符实现$avg运算符,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.本例的目标不是实现新功能,而是用熟悉的逻辑说明$accumulator
运算符的行为和语法。
From the mongo shell, create a sample collection named 从books
with the following documents:mongo
shell创建一个名为books
的样本集合,其中包含以下文档:
The following operation groups the documents by 下面的操作groups按author
, and uses $accumulator to compute the average number of copies across books for each author:author
对文档进行分组,并使用$accumulator计算每个作者在不同书籍中的平均副本数:
This operation returns the following result:此操作返回以下结果:
The $accumulator defines an initial state where count
and sum
are both set to 0
. $accumulator
定义了一个初始状态,其中count
和sum
都设置为0
。For each document that the $accumulator processes, it updates the state by:对于$accumulator
处理的每个文档,它通过以下方式更新状态:
count
by 1 andcount
增加1,然后copies
field to the sum
. copies
字段的值添加到sum
。copies
field because it is passed in the accumulateArgs field.accumulate
函数可以访问copies
字段,因为它是在accumulateArgs
字段中传递的。With each document that is processed, the accumulate function returns the updated state.对于处理的每个文档,accumulate
函数都会返回更新的状态。
Once all documents have been processed, the finalize function divides the 处理完所有文档后,sum
of the copies by the count
of documents to obtain the average. finalize
函数将副本总数sum
除以文档数count
,以获得平均值。This removes the need to keep a running computed average, since the finalize function receives the cumulative 由于sum
and count
of all documents.finalize
函数接收所有文档的累积sum
和count
,因此无需保持运行计算的平均值。
initArgs
to Vary the Initial State by GroupinitArgs
按组更改初始状态¶You can use the initArgs option in to vary the initial state of $accumulator. 您可以在中使用initArgs选项来更改$accumulator
的初始状态。This can be useful if you want to, for example:如果您想,这可能很有用,例如:
From the mongo shell, create a sample collection named 从restaurants
with the following documents:mongo
shell中,创建一个名为restaurants
的样本集合,其中包含以下文档:
Suppose an application allows users to query this data to find restaurants.假设一个应用程序允许用户查询这些数据来查找餐馆。It may be useful to show more results for the city where the user lives.为用户居住的城市显示更多结果可能很有用。For this example, we assume that the user’s city is called in a variable called 在本例中,我们假设用户的城市在名为userProfileCity
.userProfileCity
的变量中调用。
The following aggregation pipeline groups the documents by 以下聚合管道groups按city
.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:该操作使用$accumulator显示来自每个城市的不同数量的结果,具体取决于餐厅的城市是否与用户配置文件中的城市匹配:
Note
To execute this example in the mongo shell, replace 要在<userProfileCity>
in the initArgs with a string containing an actual city value, such as Bettles
.mongo
shell中执行此示例,请将initArgs中的<userProfileCity>
替换为包含实际城市值的字符串,例如Bettles
。
If the value of 如果userProfileCity
is Bettles
, this operation returns the following result:userProfileCity
的值为Bettles
,则此操作返回以下结果:
If the value of 如果userProfileCity
is Onida
, this operation returns the following result:userProfileCity
的值为Onida
,则此操作返回以下结果:
If the value of 如果userProfileCity
is Pyote
, this operation returns the following result:userProfileCity
的值为Pyote
,则此操作返回以下结果:
If the value of 如果userProfileCity
is any other value, this operation returns the following result:userProfileCity
的值是任何其他值,则此操作返回以下结果:
The init function defines an initial state containing max
and restaurants
fields.init
函数定义一个初始状态,其中包含max
字段和restaurants
字段。The max
field sets the maximum number of restaurants for that particular group.max
字段设置该特定组的最大餐厅数。If the document’s 如果文档的city
field matches userProfileCity
, that group contains a maximum of 3 restaurants.city
字段与userProfileCity
匹配,则该组最多包含3家餐厅。Otherwise, if the document 否则,如果文档_id
does not match userProfileCity
, the group contains at most a single restaurant. _id
与userProfileCity
不匹配,则该组最多包含一家餐厅。The init function receives both the city
userProfileCity
arguments from the initArgs array.init
函数从initArgs
数组接收city
userProfileCity
参数。
For each document that the $accumulator processes, it pushes the 对于$accumulator处理的每个文档,它都会将餐厅的name
of the restaurant to the restaurants
array, provided that name would not put the length of restaurants
over the max
value. name
推送到restaurants
数组,前提是该名称不会使restaurants
的长度超过max
值。With each document that is processed, the accumulate function returns the updated state.对于处理的每个文档,accumulate
函数都会返回更新的状态。
The merge function defines how to merge two states.merge
函数定义如何合并两个状态。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.restaurant
数组连接在一起,并使用slice()方法限制生成数组的长度,以确保其不超过max
值。
Once all documents have been processed, the finalize function modifies the resulting state to only return the names of the restaurants. 处理完所有文档后,finalize
函数会修改结果状态,只返回餐厅的名称。Without this function, the 如果没有此功能,输出中也会包含max
field would also be included in the output, which does not fulfill any needs for the application.max
字段,这无法满足应用程序的任何需求。