https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch/
$elemMatch (query)
TIP
See also:
Definition
$elemMatch
-
The
$elemMatch
operator matches documents that contain an array field with at least one element that matches all the specified query criteria.{ <field>: { $elemMatch: { <query1>, <query2>, ... } } } If you specify only a single
<query>
condition in the$elemMatch
expression, and are not using the$not
or$ne
operators inside of$elemMatch
,$elemMatch
can be omitted. See Single Query Condition.
Behavior
-
You cannot specify a
$where
expression in an$elemMatch
. -
You cannot specify a
$text
query expression in an$elemMatch
.
Examples
Element Match
Given the following documents in the scores
collection:
{ _id: 1, results: [ 82, 85, 88 ] } |
{ _id: 2, results: [ 75, 88, 89 ] } |
The following query matches only those documents where the results
array contains at least one element that is both greater than or equal to 80
and is less than 85
:
db.scores.find( |
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } } |
) |
The query returns the following document since the element 82
is both greater than or equal to 80
and is less than 85
:
{ "_id" : 1, "results" : [ 82, 85, 88 ] } |
For more information on specifying multiple criteria on array elements, see Specify Multiple Conditions for Array Elements.
Array of Embedded Documents
This statement inserts documents into the survey
collection:
db.survey.insertMany( [ |
{ "_id": 1, "results": [ { "product": "abc", "score": 10 }, |
{ "product": "xyz", "score": 5 } ] }, |
{ "_id": 2, "results": [ { "product": "abc", "score": 8 }, |
{ "product": "xyz", "score": 7 } ] }, |
{ "_id": 3, "results": [ { "product": "abc", "score": 7 }, |
{ "product": "xyz", "score": 8 } ] }, |
{ "_id": 4, "results": [ { "product": "abc", "score": 7 }, |
{ "product": "def", "score": 8 } ] } |
] ) |
The following query matches only those documents where the results
array contains at least one element with both product
equal to "xyz"
and score
greater than or equal to 8
:
db.survey.find( |
{ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } |
) |
Specifically, the query matches the following document:
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "xyz", "score" : 8 } ] } |
Single Query Condition
If you specify a single query predicate in the $elemMatch
expression, and are not using the $not
or $ne
operators inside of $elemMatch
, $elemMatch
can be omitted.
The following examples return the same documents.
With $elemMatch
:
db.survey.find( |
{ results: { $elemMatch: { product: "xyz" } } } |
) |
Without $elemMatch
:
db.survey.find( |
{ "results.product": "xyz" } |
) |
However, if your $elemMatch
expression contains the $not
or $ne
operators then omitting the $elemMatch
expression changes the documents returned.
The following examples return different documents.
With $elemMatch
:
db.survey.find( |
{ "results": { $elemMatch: { product: { $ne: "xyz" } } } } |
) |
Without $elemMatch
:
db.survey.find( |
{ "results.product": { $ne: "xyz" } } |
) |
With $elemMatch
, the first query returns these documents:
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, |
{ "product" : "xyz", "score" : 5 } ] } |
{ "_id" : 2, "results" : [ { "product" : "abc", "score" : 8 }, |
{ "product" : "xyz", "score" : 7 } ] } |
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "xyz", "score" : 8 } ] } |
{ "_id" : 4, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "def", "score" : 8 } ] } |
Without $elemMatch
, the second query returns this document:
{ "_id" : 4, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "def", "score" : 8 } ] } |
$elemMatch (query)
TIP
See also:
Definition
$elemMatch
-
The
$elemMatch
operator matches documents that contain an array field with at least one element that matches all the specified query criteria.{ <field>: { $elemMatch: { <query1>, <query2>, ... } } } If you specify only a single
<query>
condition in the$elemMatch
expression, and are not using the$not
or$ne
operators inside of$elemMatch
,$elemMatch
can be omitted. See Single Query Condition.
Behavior
-
You cannot specify a
$where
expression in an$elemMatch
. -
You cannot specify a
$text
query expression in an$elemMatch
.
Examples
Element Match
Given the following documents in the scores
collection:
{ _id: 1, results: [ 82, 85, 88 ] } |
{ _id: 2, results: [ 75, 88, 89 ] } |
The following query matches only those documents where the results
array contains at least one element that is both greater than or equal to 80
and is less than 85
:
db.scores.find( |
{ results: { $elemMatch: { $gte: 80, $lt: 85 } } } |
) |
The query returns the following document since the element 82
is both greater than or equal to 80
and is less than 85
:
{ "_id" : 1, "results" : [ 82, 85, 88 ] } |
For more information on specifying multiple criteria on array elements, see Specify Multiple Conditions for Array Elements.
Array of Embedded Documents
This statement inserts documents into the survey
collection:
db.survey.insertMany( [ |
{ "_id": 1, "results": [ { "product": "abc", "score": 10 }, |
{ "product": "xyz", "score": 5 } ] }, |
{ "_id": 2, "results": [ { "product": "abc", "score": 8 }, |
{ "product": "xyz", "score": 7 } ] }, |
{ "_id": 3, "results": [ { "product": "abc", "score": 7 }, |
{ "product": "xyz", "score": 8 } ] }, |
{ "_id": 4, "results": [ { "product": "abc", "score": 7 }, |
{ "product": "def", "score": 8 } ] } |
] ) |
The following query matches only those documents where the results
array contains at least one element with both product
equal to "xyz"
and score
greater than or equal to 8
:
db.survey.find( |
{ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } |
) |
Specifically, the query matches the following document:
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "xyz", "score" : 8 } ] } |
Single Query Condition
If you specify a single query predicate in the $elemMatch
expression, and are not using the $not
or $ne
operators inside of $elemMatch
, $elemMatch
can be omitted.
The following examples return the same documents.
With $elemMatch
:
db.survey.find( |
{ results: { $elemMatch: { product: "xyz" } } } |
) |
Without $elemMatch
:
db.survey.find( |
{ "results.product": "xyz" } |
) |
However, if your $elemMatch
expression contains the $not
or $ne
operators then omitting the $elemMatch
expression changes the documents returned.
The following examples return different documents.
With $elemMatch
:
db.survey.find( |
{ "results": { $elemMatch: { product: { $ne: "xyz" } } } } |
) |
Without $elemMatch
:
db.survey.find( |
{ "results.product": { $ne: "xyz" } } |
) |
With $elemMatch
, the first query returns these documents:
{ "_id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, |
{ "product" : "xyz", "score" : 5 } ] } |
{ "_id" : 2, "results" : [ { "product" : "abc", "score" : 8 }, |
{ "product" : "xyz", "score" : 7 } ] } |
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "xyz", "score" : 8 } ] } |
{ "_id" : 4, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "def", "score" : 8 } ] } |
Without $elemMatch
, the second query returns this document:
{ "_id" : 4, "results" : [ { "product" : "abc", "score" : 7 }, |
{ "product" : "def", "score" : 8 } ] } |