$and$andperforms a logicalANDoperation on an array of one or more expressions (<expression1>,<expression2>, and so on) and selects the documents that satisfy all the expressions.Note
MongoDB provides an implicit
ANDoperation when specifying a comma separated list of expressions.
Compatibility
You can use $and for deployments hosted in the following environments:
MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: The subscription-based, self-managed version of MongoDB
MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB
Syntax
The $and has the following syntax:
{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
Behavior
When evaluating the clauses in the $and expression, MongoDB's query optimizer considers which indexes are available that could help satisfy clauses of the $and expression when selecting the best plan to execute.
To allow the query engine to optimize queries, $and handles errors as follows:
If any expression supplied to
$andwould cause an error when evaluated alone, the$andcontaining the expression may cause an error but an error is not guaranteed.An expression supplied after the first expression supplied to
$andmay cause an error even if the first expression evaluates tofalse.
For example, the following query always produces an error if $x is 0:
db.example.find( { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } )
The following query, which contains multiple expressions supplied to $and, may produce an error if there is any document where $x is 0:
db.example.find( { $and: [ { x: { $ne: 0 } }, { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } ] } )
Most programming languages and drivers, including the MongoDB Shell (mongosh), do not allow the construction of objects with duplicate keys at the same object level. For example, consider this query:
db.inventory.find( { price: { $in: [ 7.99, 3.99 ], $in: [ 4.99, 1.99 ] } } )
The above query does not construct correctly because the field name price has duplicate operators at the same object level. As a result, the query sent to the server differs from what is intended. For the query to work as expected, use an explicit AND operator:
db.inventory.find( { $and: [ { price: { $in: [ 7.99, 3.99 ] } }, { price: { $in: [ 4.99, 1.99 ] } } ] } )
This query explicitly checks that both conditions are satisfied: the price array must include at least one value from each $in set. For more information on how to address such scenarios, see the Examples section.
Examples
$and Queries With Multiple Expressions Specifying the Same Field
Consider this query:
db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
The query selects all documents in the inventory collection where:
the
pricefield value is not equal to1.99andthe
pricefield exists.
You can simplify this query by combining the operator expressions for the price field into a single query object with a nested implicit AND:
db.inventory.find( { price: { $ne: 1.99, $exists: true } } )
Sometimes such rewrites are not possible, particularly when dealing with duplicate conditions on the same field. For example:
db.inventory.find( { status: { $ne: "closed", $ne: "archived" } } )
The above query does not construct correctly because it uses the $ne operator more than once on the same status field name at the same object level. In this case, the $nin operator provides a more effective solution:
db.inventory.find( { status: { $nin: [ "closed", "archived" ] } } )
How you rewrite a query depends on the intended semantics of your use case. Consider the following query:
db.inventory.find( { $and: [ { status: "new" }, { status: "processing" } ] } )
If you want to find documents where status is either new or processing, you can use the $in operator:
db.inventory.find( { status: { $in: [ "new", "processing" ] } } )
If your status field is an array [ "new", "processing" ], and you want to check if the document contains both the new and processing values, use the $all operator:
db.inventory.find( { status: { $all: [ "new", "processing" ] } } )
In this context, this query is semantically equivalent to AND, but $all is often clearer when querying array fields.
Similar to duplicate field names, the same considerations apply for duplicate operators used in the query.