$where
定义
$where
重要
服务器端JavaScript已弃用
从 MongoDB 8.0 开始,服务器端 JavaScript 函数(
$accumulator
、$function
、$where
)将弃用。运行这些函数时,MongoDB 会记录警告。使用
$where
操作符将包含 JavaScript 表达式或完整 JavaScript 函数的字符串传递给查询系统。$where
提供了更高的灵活性,但要求数据库为集合中的每份 文档处理 JavaScript 表达式或函数。使用this
或obj
在 JavaScript 表达式或函数中引用此文档。
兼容性
可以使用 $where
查找托管在以下环境中的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$where
操作符采用以下形式:
{ $where: <string|JavaScript Code> }
注意
行为
可用 JavaScript 属性和函数
map-reduce operations
和 $where
操作符表达式无法访问 mongosh
中可用的某些全局函数或属性,例如 db
。
以下 JavaScript 函数和属性可用于 map-reduce operations
和 $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() Timestamp() tojson() tojsononeline() tojsonObject() UUID() version() |
elemMatch
仅对顶级文档应用 $where
查询操作符。$where
查询操作符不适用于嵌套式文档(例如 $elemMatch
查询)。
Considerations
请勿使用全局变量。
$where
会对 JavaScript 进行求值,并且无法利用索引。因此,使用标准 MongoDB 运算符(例如$gt
、$in
)来表达查询时,查询性能会提高。通常,只有在无法使用其他运算符表达查询时,才应使用
$where
。如果必须使用$where
,尽量包含至少一个其他标准查询操作符来过滤结果集。单独使用$where
需进行集合扫描。
使用常规的非 $where
查询语句具有以下性能优势:
JavaScript Enablement
要使用 $where
(或 $function
、$accumulator
或 mapReduce
),必须启用服务器端脚本(默认)。
但是,如果不使用这些操作,请禁用服务器端脚本:
对于
mongod
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。对于
mongos
实例,请参阅security.javascriptEnabled
配置选项或--noscripting
命令行选项。
另请参阅 ➤使用安全配置选项运行 MongoDB。
不支持的数组与字符串函数
MongoDB 6.0 升级了用于服务器端 JavaScript、$accumulator
、$function
和 $where
表达式的内部 JavaScript 引擎,并从 MozJS-60 升级到 MozJS-91。MozJS-91 已删除 MozJS-60 中存在的若干已弃用的非标准数组和字符串函数。
有关已删除数组和字符串函数的完整列表,请参阅 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 中定义自定义聚合表达式。要访问 db.collection.find()
中的 $function
和其他聚合操作符,请与 $expr
一起使用:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "9b53e667f30cd329dca1ec9e6a83e994"; }, args: [ "$name" ], lang: "js" } } } )