$function(聚合)
定义
$function
在 JavaScript 中定义一个自定义聚合函数或表达式。
您可以使用
$function
操作符定义自定义函数,以实施 MongoDB 查询语言不支持的行为。另请参阅$accumulator
。
语法
$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。
另请参阅 ➤使用安全配置选项运行 MongoDB。
的替代方案 $where
查询操作符$where
也可用于指定 JavaScript 表达式。然而:
如果提供的管道操作符无法满足应用程序的需求,则
$function
和$accumulator
允许用户在 JavaScript 中定义自定义聚合表达式。
给定可用的聚合操作符:
将
$expr
与不使用 JavaScript 的聚合操作符(即非$function
和非$accumulator
操作符)一起使用比$where
更快,因为它不执行 JavaScript,因此应尽可能作为首选。但是,如果必须创建自定义表达式,则
$function
比$where
更可取。
不支持的数组与字符串函数
MongoDB6 。0 升级用于 服务器端 JavaScript 、 、$accumulator
$function
和 表达式的内部$where
JavaScript 引擎,并从 MozJS-60 升级到 MozJS-91 。 MozJS- 中存在的几个已弃用的非标准数组和字符串函数已在60 MozJS-91 中删除。
有关已删除数组和字符串函数的完整列表,请参阅 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
为每份文档添加新字段:
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
$expr
操作符允许在查询语言中使用聚合表达式。如果提供的管道操作符无法满足应用程序的需求,则$function
和$accumulator
允许用户在 JavaScript 中定义自定义聚合表达式。
给定可用的聚合操作符:
将
$expr
与不使用 JavaScript 的聚合操作符(即非$function
和非$accumulator
操作符)一起使用比$where
更快,因为它不执行 JavaScript,因此应尽可能作为首选。但是,如果必须创建自定义表达式,则
$function
比$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" } } } )