On this page本页内容
Changed in version 5.0.在版本5.0中更改。
$expr
Allows the use of aggregation expressions within the query language.允许在查询语言中使用聚合表达式。
$expr has the following syntax:具有以下语法:
{ $expr: { <expression> } }
The arguments can be any valid aggregation expression. 参数可以是任何有效的聚合表达式。For more information, see Expressions.有关详细信息,请参阅表达式。
$expr can build query expressions that compare fields from the same document in a 可以生成查询表达式,用于在$match stage.$match阶段中比较同一文档中的字段。
If the 如果$match stage is part of a $lookup stage, $expr can compare fields using let variables. $match阶段是$lookup阶段的一部分,$expr可以使用let变量比较字段。See Perform Multiple Joins and a Correlated Subquery with 有关示例,请参阅使用$lookup for an example.$lookup执行多个联接和相关子查询。
Starting in MongoDB 5.0, the 从MongoDB 5.0开始,放置在$eq, $lt, $lte, $gt, and $gte comparison operators placed in an $expr operator can use an index on the from collection referenced in a $lookup stage. $expr运算符中的$eq、$lt、$lte、$gt和$gte比较运算符可以在$lookup阶段引用的from集合上使用索引。Limitations:限制:
Consider an 考虑具有以下文档的monthlyBudget collection with the following documents:monthlyBudget集合:
{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
The following operation uses 以下操作使用$expr to find documents where the spent amount exceeds the budget:$expr查找spent(花费)金额超过budget(预算)的文档:
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )
The operation returns the following results:该操作返回以下结果:
{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }
$expr With Conditional Statements$expr与条件语句一起使用Some queries require the ability to execute conditional logic when defining a query filter. 在定义查询筛选器时,某些查询需要执行条件逻辑。The aggregation pipeline provides the 聚合管道提供$cond operator to express conditional statements. $cond运算符来表示条件语句。By using 通过将$expr with the $cond operator, you can specify a conditional filter for your query statement.$expr与$cond运算符一起使用,可以为查询语句指定条件筛选器。
Create a sample 使用以下文档创建示例supplies collection with the following documents:supplies集合:
db.supplies.insertMany([
{ "_id" : 1, "item" : "binder", "qty" : NumberInt("100"), "price" : NumberDecimal("12") },
{ "_id" : 2, "item" : "notebook", "qty" : NumberInt("200"), "price" : NumberDecimal("8") },
{ "_id" : 3, "item" : "pencil", "qty" : NumberInt("50"), "price" : NumberDecimal("6") },
{ "_id" : 4, "item" : "eraser", "qty" : NumberInt("150"), "price" : NumberDecimal("3") },
{ "_id" : 5, "item" : "legal pad", "qty" : NumberInt("42"), "price" : NumberDecimal("10") }
])
Assume that for an upcoming sale next month, you want to discount the prices such that:假设对于下个月即将进行的销售,您希望对价格进行折扣,以便:
qty is greater than or equal to 100, the discounted price will be 0.5 of the price.qty大于或等于100,折扣价格将为price的0.5。qty is less than 100, the discounted price is 0.75 of the price.qty小于100,折扣价为price的0.75。Before applying the discounts, you would like to know which items in the 在应用折扣之前,您想知道supplies collection have a discounted price of less than 5.supplies集合中哪些项目的折扣价格低于5。
The following example uses 以下示例使用$expr with $cond to calculate the discounted price based on the qty and $lt to return documents whose calculated discount price is less than NumberDecimal("5"):$expr和$cond根据qty计算折扣价格,并使用$lt返回计算折扣价格小于NumberDecimal("5")的文档:
// Aggregation expression to calculate discounted price let discountedPrice = { $cond: { if: { $gte: ["$qty", 100] }, then: { $multiply: ["$price", NumberDecimal("0.50")] }, else: { $multiply: ["$price", NumberDecimal("0.75")] } } }; // Query the supplies collection using the aggregation expression db.supplies.find( { $expr: { $lt:[ discountedPrice, NumberDecimal("5") ] } });
The following table shows the discounted price for each document and whether discounted price is less than 下表显示了每张单据的折扣价格,以及折扣价格是否小于NumberDecimal("5") (i.e. whether the document meets the query condition).NumberDecimal("5")(即单据是否满足查询条件)。
| Document | Discounted Price | < NumberDecimal("5") |
|---|---|---|
{"_id": 1, "item": "binder", "qty": 100, "price": NumberDecimal("12") } | NumberDecimal("6.00") | false |
{"_id": 2, "item": "noteboook", "qty": 200, "price": NumberDecimal("8") } | NumberDecimal("4.00") | true |
{"_id": 3, "item": "pencil", "qty": 50, "price": NumberDecimal("6") } | NumberDecimal("4.50") | true |
{"_id": 4, "item": "eraser", "qty": 150, "price": NumberDecimal("3") } | NumberDecimal("1.50") | true |
{"_id": 5, "item": "legal pad", "qty": 42, "price": NumberDecimal("10") } | NumberDecimal("7.50") | false |
The db.collection.find() operation returns the documents whose calculated discount price is less than NumberDecimal("5"):db.collection.find()操作返回计算出的折扣价格小于NumberDecimal("5")的文档:
{ "_id" : 2, "item" : "notebook", "qty": 200 , "price": NumberDecimal("8") }
{ "_id" : 3, "item" : "pencil", "qty": 50 , "price": NumberDecimal("6") }
{ "_id" : 4, "item" : "eraser", "qty": 150 , "price": NumberDecimal("3") }
Even though 即使$cond calculates an effective discounted price, that price is not reflected in the returned documents. $cond计算了有效的折扣价格,该价格也不会反映在返回的文档中。Instead, the returned documents represent the matching documents in their original state. 相反,返回的文档表示原始状态下的匹配文档。The find operation did not return the 查找操作未返回binder or legal pad documents, as their discounted price was greater than 5.binder或legal pad文档,因为它们的折扣价格大于5。