Database Manual / Reference / Query Language / Expressions

$function (expression operator)(表达式运算符)

Definition定义

$function

Important

Server-side JavaScript Deprecated服务器端JavaScript已弃用

Starting in MongoDB 8.0, server-side JavaScript functions ($accumulator, $function, $where) are deprecated. MongoDB logs a warning when you run these functions.从MongoDB 8.0开始,服务器端JavaScript函数($accumulator$function$where)被弃用。当您运行这些函数时,MongoDB会记录一个警告。

Defines a custom aggregation function or expression in JavaScript.在JavaScript中定义自定义聚合函数或表达式。

You can use the $function operator to define custom functions to implement behavior not supported by the MongoDB Query Language. 您可以使用$function运算符定义自定义函数来实现MongoDB查询语言不支持的行为。See also $accumulator.另请参见$accumulator

Important

Executing JavaScript inside an aggregation expression may decrease performance. 在聚合表达式中执行JavaScript可能会降低性能。Only use the $function operator if the provided pipeline operators cannot fulfill your application's needs.仅当提供的管道运算符无法满足应用程序的需求时,才使用$function运算符。

Syntax语法

The $function operator has the following syntax:$function运算符具有以下语法:

{
$function: {
body: <code>,
args: <array expression>,
lang: "js"
}
}
Field字段Type类型Description描述
bodyString or Code字符串或代码

The function definition. You can specify the function definition as either BSON type Code or String. See also lang.函数定义。您可以将函数定义指定为BSON类型的Code或String。另请参阅lang

function(arg1, arg2, ...) { ... }

or

"function(arg1, arg2, ...) { ... }"

argsArray数组

Arguments passed to the function body. If the body function does not take an argument, you can specify an empty array [ ].传递给函数body的参数。如果body函数不接受参数,则可以指定一个空数组[]

The array elements can be any BSON type, including Code. See Example 2: Alternative to $where.数组元素可以是任何BSON类型,包括Code。请参见示例2:$where的替代方案

langString字符串

The language used in the body. You must specify lang: "js".body中使用的语言。您必须指定lang: "js"

Considerations注意事项

Schema Validation Restriction架构验证限制

You cannot use $function as part of a schema validation query predicate.您不能将$function用作架构验证查询谓词的一部分。

Javascript EnablementJavascript启用

To use $function, you must have server-side scripting enabled (default).要使用$function,您必须启用服务器端脚本(默认)。

If you do not use $function (or $accumulator, $where, or mapReduce), disable server-side scripting:如果不使用$function(或$accumulator$wheremapReduce),请禁用服务器端脚本:

See also ➤ Run MongoDB with Secure Configuration Options.另请参阅➤ 使用安全配置选项运行MongoDB

Alternative to $where替代$where

The query operator $where can also be used to specify JavaScript expression. However:查询运算符$where也可用于指定JavaScript表达式。然而:

  • The $expr operator allows the use of aggregation expressions within the query language.$expr运算符允许在查询语言中使用聚合表达式
  • The $function and $accumulator allows users to define custom aggregation expressions in JavaScript if the provided pipeline operators cannot fulfill your application's needs.如果提供的管道运算符无法满足应用程序的需求,$function$accumulator允许用户在JavaScript中定义自定义聚合表达式。

Given the available aggregation operators:给定可用的聚合运算符:

  • The use of $expr with aggregation operators that do not use JavaScript (i.e. non-$function and non-$accumulator operators) is faster than $where because it does not execute JavaScript and should be preferred if possible.$expr与不使用JavaScript的聚合运算符(即非$function和非$accumulator运算符)一起使用比$where更快,因为它不执行JavaScript,如果可能的话应该是首选。
  • However, if you must create custom expressions, $function is preferred over $where.但是,如果必须创建自定义表达式,则$function$where更可取。

Unsupported Array and String Functions不支持的数组和字符串函数

MongoDB 6.0 upgrades the internal JavaScript engine used for server-side JavaScript, $accumulator, $function, and $where expressions and from MozJS-60 to MozJS-91. Several deprecated, non-standard array and string functions that existed in MozJS-60 are removed in MozJS-91.MongoDB 6.0将用于服务器端JavaScript$accumulator$function$where表达式的内部JavaScript引擎从MozJS-60升级到MozJS-91。MozJS-60中存在的几个已弃用的非标准数组和字符串函数在MozJS-91中被删除。

Examples示例

Example 1: Usage Example示例1:使用示例

Create a sample collection named players with the following documents:使用以下文档创建一个名为players的示例集合:

db.players.insertMany([
{ _id: 1, name: "Miss Cheevous", scores: [ 10, 5, 10 ] },
{ _id: 2, name: "Miss Ann Thrope", scores: [ 10, 10, 10 ] },
{ _id: 3, name: "Mrs. Eppie Delta ", scores: [ 9, 8, 8 ] }
])

The following aggregation operation uses $addFields to add new fields to each document:以下聚合操作使用$addFields向每个文档添加新字段:

  • isFound whose value is determined by the custom $function expression that checks whether the MD5 hash of the name is equal to a specified hash.isFound,其值由自定义$function表达式确定,该表达式检查名称的MD5哈希是否等于指定的哈希。
  • message whose value is determined by the custom $function expression that format a string message using a template.其值由使用模板格式化字符串消息的自定义$function表达式确定的消息。
db.players.aggregate( [
{ $addFields:
{
isFound:
{ $function:
{
body: function(name) {
return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"
},
args: [ "$name" ],
lang: "js"
}
},
message:
{ $function:
{
body: function(name, scores) {
let total = Array.sum(scores);
return `Hello ${name}. Your total score is ${total}.`
},
args: [ "$name", "$scores"],
lang: "js"
}
}
}
}
] )

The operation returns the following documents:该操作返回以下文档:

{ "_id" : 1, "name" : "Miss Cheevous", "scores" : [ 10, 5, 10 ], "isFound" : false, "message" : "Hello Miss Cheevous.  Your total score is 25." }
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ], "isFound" : true, "message" : "Hello Miss Ann Thrope. Your total score is 30." }
{ "_id" : 3, "name" : "Mrs. Eppie Delta ", "scores" : [ 9, 8, 8 ], "isFound" : false, "message" : "Hello Mrs. Eppie Delta . Your total score is 25." }

Example 2: Alternative to $where示例2:替代$where

Note

Aggregation Alternatives Preferred over $where聚合替代方案优于$where

The $expr operator allows the use of aggregation expressions within the query language. $expr运算符允许在查询语言中使用聚合表达式And the $function and $accumulator allows users to define custom aggregation expressions in JavaScript if the provided pipeline operators cannot fulfill your application's needs.如果提供的管道运算符无法满足应用程序的需求,$function$accumulator允许用户在JavaScript中定义自定义聚合表达式。

Given the available aggregation operators:给定可用的聚合运算符:

  • The use of $expr with aggregation operators that do not use JavaScript (i.e. non-$function and non-$accumulator operators) is faster than $where because it does not execute JavaScript and should be preferred if possible.$expr与不使用JavaScript的聚合运算符(即非$function和非$accumulator运算符)一起使用比$where更快,因为它不执行JavaScript,如果可能的话应该是首选。
  • However, if you must create custom expressions, $function is preferred over $where.但是,如果必须创建自定义表达式,则$function$where更可取。

As an alternative to a query that uses the $where operator, you can use $expr and $function. For example, consider the following $where example.作为使用$where运算符的查询的替代方法,您可以使用$expr$function。例如,考虑以下$where示例。

db.players.find( { $where: function() {
return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad")
} } );

The db.collection.find() operation returns the following document:db.collection.find()操作返回以下文档:

{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ] }

The example can be expressed using $expr and $function:这个例子可以用$expr$function来表示:

db.players.find( {$expr: { $function: {
body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; },
args: [ "$name" ],
lang: "js"
} } } )