Hi,
The $elemMatch projection has the limitation that it will only project the first matching element. This is mentioned in the $elemMatch projection documentation page.
To display all matching elements, you need to use the Aggregation framework.
You didn’t give an example document you’re trying to match, but I assume it’s similar to this:
{
"name": "Restaurant A",
"grades": [
{
"reviewer": "a",
"score": 10
},
{
"reviewer": "b",
"score": 10
},
{
"reviewer": "c",
"score": 9
}
]
}
The aggregation stages you can use depends on your MongoDB version. If you’re using MongoDB 3.4, you can use the new $addFields stage:
db.restaurants.aggregate([
// match the relevant document
{$match:{'grades.score':{$gte: 10}}},
// filter out irrelevant array entries
{$addFields: {
top_reviews: {
$filter: {
input: '$grades',
cond: {
$gte: ['$$this.score', 10]
}
}
}
}},
// project only the relevant fields
{$project: {_id: 0, grades: 0}}
])
or if you’re using older versions of MongoDB, you would need to use the relatively less-performant $unwind stage:
db.restaurants.aggregate([
// match relevant documents
{$match: {'grades.score': {$gte: 10}}},
// unwind the grades array
{$unwind: '$grades'},
// match the relevant unwound array element
{$match: {'grades.score': {$gte: 10}}},
// re-group the array elements
{$group: {
_id: '$name',
top_reviews: {$push: '$grades'}
}}
])
Either way, both methods should result in:
{ "name": "Restaurant A", "top_reviews": [ { "reviewer": "a", "score": 10 }, { "reviewer": "b", "score": 10 } ] }
Here are the relevant documentations regarding the aggregation stages:
Best regards,
Kevin
Hi
But, why to specify filter condition i.e. score >10 mutiple times?
I believe you are referring to the $unwind example. This is due to how $unwind works, i.e. it’s unwinding the array into separate documents. Hence the first $match is to filter irrelevant documents, and the second $match is to filter out irrelevant unwound array entries.
Please see the $unwind documentation page.
Best regards,
Kevin
Hi Tran
Can you help me to convert this query to java.
I’m not certain what query you want to convert to Java. In general, the Java driver syntax follows the mongo shell syntax quite closely. See MongoDB Driver Quick Start for some examples.
If you need more help, could you open a new thread with more details, e.g. your Java driver version and the query you’re having issues with.
Best regards,
Kevin