- $and
- $andperforms a logical- ANDoperation 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 to- false.
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 to- 1.99and
- the - 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.