$where
定义
$where
重要
服务器端JavaScript已弃用
从MongoDB 8.0开始,服务器端JavaScript函数(
$accumulator
、$function
、$where
)已被弃用。当您运行这些函数时,MongoDB会记录一条警告。使用
$where
运算符来传递包含JavaScript表达式的字符串或完整的JavaScript函数。与$where
相比,它提供了更大的灵活性,但需要数据库处理集合中的每个文档的JavaScript表达式或函数。使用this
或obj
在JavaScript表达式或函数中引用文档。
兼容性
您可以在以下环境中使用 $where
部署
MongoDB Atlas:云中MongoDB部署的全托管服务
MongoDB 企业版:基于订阅的自托管MongoDB版本
MongoDB 社区版:源代码公开、免费使用并可自托管的MongoDB版本
语法
$where
操作符具有以下形式
{ $where: <string|JavaScript Code> }
注意
注意
优先考虑聚合替代方案
$expr
操作符允许在查询语言中使用 聚合表达式。当提供的 管道操作符 无法满足应用程序需求时,$function
和 $accumulator
允许用户在 JavaScript 中定义自定义聚合表达式。
给定可用的聚合操作符
使用不涉及JavaScript的聚合运算符(即非
$function
和$accumulator
运算符)的$expr
,其速度比使用$where
快,因为它不需要执行JavaScript,如果可能的话,应优先使用。然而,如果您必须创建自定义表达式,则比使用
$where
更推荐使用$function
。
行为
可用的JavaScript属性和函数
map-reduce操作
和$where
运算符表达式无法访问某些全局函数或属性,例如在mongosh
中可用的db
。
以下JavaScript函数和属性在map-reduce操作
和$where
运算符表达式中可用
可用的属性 | 可用的函数 | |
---|---|---|
args MaxKey MinKey | assert() BinData() DBPointer() DBRef() doassert() emit() gc() HexData() hex_md5() isNumber() isObject() ISODate() isString() | Map() MD5() NumberInt() NumberLong() ObjectId() print() printjson() printjsononeline() sleep() 时间戳() tojson() tojsononeline() tojsonObject() UUID() 版本号() |
elemMatch
仅将 $where
查询运算符应用于顶层文档。在嵌套文档内部,例如在 $elemMatch
查询中,$where
查询运算符将不起作用。
注意事项
不要使用全局变量。
$where
评估 JavaScript 并且无法利用索引。因此,当您使用标准的 MongoDB 操作符(例如,$gt
,$in
)表达查询时,查询性能会得到提升。一般来说,您应该只在无法使用其他运算符表达查询时才使用
$where
。如果您必须使用$where
,则尝试包含至少一个其他标准查询运算符以过滤结果集。单独使用$where
需要集合扫描。
使用常规非 $where
查询语句提供以下性能优势
JavaScript启用
要使用$where
(或$function
、$accumulator
或mapReduce
),您必须启用服务器端脚本(默认设置)。
然而,如果您不使用这些操作,请禁用服务器端脚本
对于
mongod
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。对于
mongos
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。
不支持数组字符串函数
MongoDB 6.0 版本升级了用于服务器端 JavaScript、$accumulator
、$function
和$where
表达式所使用的内部JavaScript引擎,从MozJS-60升级到MozJS-91。在MozJS-60中存在的几个已弃用、非标准的数组和字符串函数在MozJS-91中被移除。
有关移除的数组和字符串函数的完整列表,请参阅6.0 兼容性说明。
示例
考虑以下位于players
集合中的文档
db.players.insertMany([ { _id: 12378, name: "Steve", username: "steveisawesome", first_login: "2017-01-01" }, { _id: 2, name: "Anya", username: "anya", first_login: "2001-02-02" } ])
以下示例使用$where
和hex_md5()
JavaScript 函数来比较name
字段的值与MD5散列,并返回任何匹配的文档。
db.players.find( { $where: function() { return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994") } } );
该操作返回以下结果
{ "_id" : 2, "name" : "Anya", "username" : "anya", "first_login" : "2001-02-02" }
作为替代,前面的示例可以用$expr
和$function
重写。您可以使用聚合操作符$function
在JavaScript中定义自定义聚合表达式。要访问$function
和其他聚合操作符,请在db.collection.find()
中使用$expr
:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "9b53e667f30cd329dca1ec9e6a83e994"; }, args: [ "$name" ], lang: "js" } } } )
如果您必须创建自定义表达式,则首选使用$function
而不是$where
。