定义
$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 操作符表达式:
可用属性 | 可用函数 | |
|---|---|---|
argsMaxKeyMinKey | 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 中存在的若干已弃用的非标准数组和字符串函数。
例子
以 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" } } } )