Learn the "why" behind slow queries and how to fix them in our 2-Part Webinar.
Register now >
Docs 菜单
Docs 主页
/ /

$expr(查询谓词操作符)

5.0 版本中的更改

$expr

允许在查询谓词中使用 表达式

可以使用 $expr 查找托管在以下环境中的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

{ $expr: { <expression> } }

参数可以是任何有效的表达式。

$expr 出现在属于 $lookup 子管道的 $match 阶段时, $expr 可以引用 $lookup 阶段定义的 let 变量。有关示例,请参见使用多个连接条件和关联子查询

放置在 $expr 操作符上的 $eq$lt$lte$gt$gte 比较操作符可以使用 $lookup 阶段引用的 from 集合上的索引。限制:

  • 索引只能用于字段和常量之间的比较,因此 let 操作数必须解析为常量。

    示例,$a 和常量值之间的比较可以使用索引,但 $a$b 之间的比较不能使用索引。

  • let 操作数解析为空值或缺失值时,索引不用于比较。

  • 不使用 多键部分稀疏 索引。

本页上的示例使用sample_mflix示例数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载示例数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。

$expr 可以包含对同一文档中的字段进行比较的表达式。

以下操作使用$exprmovies 集合中查找烂番茄收视率超过评论家评分的文档:

db.movies.find(
{ $expr: { $gt: [ "$tomatoes.viewer.rating", "$tomatoes.critic.rating" ] } },
{ _id: 0, title: 1, "tomatoes.viewer.rating": 1, "tomatoes.critic.rating": 1 }
).sort( { "tomatoes.viewer.rating": -1 } ).limit( 3 )
[
{ title: 'I Am Maria', tomatoes: { viewer: { rating: 5 } } },
{ title: 'Kadin Hamlet', tomatoes: { viewer: { rating: 5 } } },
{ title: 'The Seine Meets Paris', tomatoes: { viewer: { rating: 5 } } }
]

某些查询在定义查询过滤时需要执行条件逻辑。聚合管道提供$cond 操作符来表达条件语句。通过将$expr$cond 操作符一起使用,可以为查询声明指定条件筛选过滤。

假设您要计算电影的加权分数,以便收视率高但得票数少的电影不会在结果中占主导地位:

  • 如果 imdb.votes 大于或等于 1000,则加权分数为满分 imdb.rating

  • 如果 imdb.votes 小于 1000,则加权分数为 imdb.rating 的 0.5。

您想知道 movies集合中哪些电影的加权分数大于 9

以下示例使用$expr$cond 来计算基于imdb.votes$gt 的加权分数,以返回计算出的加权分数大于9 的文档:

db.movies.find(
{
"imdb.rating": { $type: "number" },
"imdb.votes": { $type: "number" },
$expr: {
$gt: [
{
$cond: {
if: { $gte: ["$imdb.votes", 1000] },
then: { $multiply: ["$imdb.rating", 1.0] },
else: { $multiply: ["$imdb.rating", 0.5] }
}
},
9
]
}
},
{ _id: 0, title: 1, "imdb.rating": 1, "imdb.votes": 1 }
).sort( { title: 1 } ).limit(5)

下表显示了所选文档的加权分数以及加权分数是否大于 9(即文档是否满足查询条件)。

文档
加权分数
> 9

{ title: "The Shawshank Redemption", imdb: { rating: 9.3, votes: 1521105 } }

9.3

true

{ title: "The Godfather", imdb: { rating: 9.2, votes: 1038358 } }

9.2

true

{ title: "Fight Club", imdb: { rating: 8.9, votes: 1191784 } }

8.9

false

{ title: "Planet Earth", imdb: { rating: 9.5, votes: 82896 } }

9.5

true

{ title: "Hollywood", imdb: { rating: 9.1, votes: 511 } }

4.55

false

db.collection.find()5操作返回计算出的加权分数大于 的9 个文档:

[
{ title: 'Band of Brothers', imdb: { rating: 9.6, votes: 183802 } },
{ title: 'Baseball', imdb: { rating: 9.1, votes: 2460 } },
{ title: 'Cosmos', imdb: { rating: 9.3, votes: 17174 } },
{ title: 'Frozen Planet', imdb: { rating: 9.2, votes: 5903 } },
{ title: 'Human Planet', imdb: { rating: 9.2, votes: 9057 } }
]

即使$cond 计算加权分数,该分数也不会反映在返回的文档中。相反,返回的文档代表原始状态下的匹配文档。

后退

其他

在此页面上