$function(聚合函数)
定义
$function
重要
服务器端JavaScript已弃用
从MongoDB 8.0开始,服务器端JavaScript函数(
$accumulator
,$function
,$where
)已弃用。运行这些函数时,MongoDB会记录警告。使用JavaScript定义自定义聚合函数或表达式。
您可以使用
$function
运算符来定义自定义函数,以实现MongoDB查询语言不支持的行为。另请参阅$accumulator
。重要
在聚合表达式中执行JavaScript可能会降低性能。只有当提供的
$function
运算符无法满足应用程序需求时,才使用它。
语法
操作符 $function
的语法如下
{ $function: { body: <code>, args: <array expression>, lang: "js" } }
注意事项
模式验证限制
您不能将 $function
用作模式验证查询谓词的一部分。
JavaScript 启用
要使用 $function
,您必须启用服务器端脚本(默认设置)。
如果您不使用 $function
(或 $accumulator
,$where
,或 mapReduce
),则禁用服务器端脚本
对于
mongod
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。对于
mongos
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。在早期版本中,MongoDB 不允许在mongos
实例上执行 JavaScript。
相对于 $where
查询运算符 $where
也可以用于指定 JavaScript 表达式。然而
操作符
$function
和$accumulator
允许用户在提供的管道操作符无法满足应用程序需求时,在 JavaScript 中定义自定义的聚合表达式。
给定可用的聚合操作符
不支持数组字符串函数
MongoDB 6.0 升级了用于 服务器端 JavaScript、$accumulator
、$function
和 $where
表达式的内部 JavaScript 引擎,从 MozJS-60 升级到 MozJS-91。MozJS-91 中移除了 MozJS-60 中存在的一些已弃用、非标准数组字符串函数。
有关移除的数组字符串函数的完整列表,请参阅 6.0 兼容性说明。
示例
示例 1:使用示例
使用以下文档创建一个名为 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 ] } ])
以下聚合操作使用 $addFields
在每个文档中添加新字段
isFound
的值由自定义的$function
表达式确定,该表达式检查名称的 MD5 哈希是否等于指定的哈希。message
的值由自定义的$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" } } } } ] )
操作返回以下文档
{ "_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." }
示例 2:$where 的替代方案
注意
优先使用聚合替代方案而非 $where
作为使用 $where
运算符的查询的替代方案,您可以使用 $expr
和 $function
。例如,考虑以下 $where
示例。
db.players.find( { $where: function() { return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad") } } );
db.collection.find()
操作返回以下文档
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ] }
该示例可以使用 $expr
和 $function
表达:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; }, args: [ "$name" ], lang: "js" } } } )