$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.