$expr¶
On this page
Definition¶
New in version 3.6.
-
$expr¶ Allows the use of aggregation expressions within the query language.
$exprhas the following syntax:The arguments can be any valid aggregation expression. For more information, see Expressions.
Behavior¶
$exprcan build query expressions that compare fields from the same document in a$matchstage.$exprdoes not support multikey indexes.
Examples¶
Compare Two Fields from A Single Document¶
Consider an monthlyBudget collection with the following documents:
The following operation uses $expr to find documents
where the spent amount exceeds the budget:
The operation returns the following results:
Using $expr With Conditional Statements¶
Some queries require the ability to execute conditional logic when
defining a query filter. The aggregation framework provides the
$cond operator to express conditional statements. By using
$expr with the $cond operator, you can
specify a conditional filter for your query statement.
Create a sample supplies collection with the following documents:
Assume that for an upcoming sale next month, you want to discount the prices such that:
- If
qtyis greater than or equal to 100, the discounted price will be 0.5 of theprice. - If
qtyis less than 100, the discounted price is 0.75 of theprice.
Before applying the discounts, you would like to know which items in the
supplies collection have a discounted price of less than 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"):
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).
| 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"):
Even though $cond calculates an effective discounted
price, that price is not reflected in the returned documents. 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.