How to apply $gte, $lte on a specific array element with $expr in $match stage of aggregation pipeline

I have a collection named students containing the following documents
{_id: 1, marks:[1,2,3,4,5]}
{_id: 2, marks:[4,2,6,4,5]}
{_id: 3, marks:[9,6,3,4,5]}
{_id: 4, marks:[6,2,2,4,7]}
{_id: 5, marks:[7,2,2,4,7]}

I want to get those documents where the value of first element of the marks array is between 3 and 8 . I am using following $expr based aggregate query. But it is returning no document. Please note I want to use $expr only.

db.students.aggregate([{
$match: {
$expr: {
“$and”: [{
“$gte”: ["$marks.0", 3]
}, {
“$lte”: ["$marks.0", 8]
}]
}
}
}])

Please help. Thanks in advanced.

Welcome to MongoDB community,
in aggregations you should use { $arrayElemAt: [ <array>, <idx> ] } or in your case the alias $first instead of the dot notation
for more information check

If you still struggle with this pipeline, let us know
Greets

1 Like

You were almost there. On the right track but a little bit too far. It is simpler:

> c = db.Sudarshan_Roy
test.Sudarshan_Roy
> c.find()
{ "_id" : 1, "marks" : [ 1, 2, 3, 4, 5 ] }
{ "_id" : 2, "marks" : [ 4, 2, 6, 4, 5 ] }
{ "_id" : 3, "marks" : [ 9, 6, 3, 4, 5 ] }
{ "_id" : 4, "marks" : [ 6, 2, 2, 4, 7 ] }
{ "_id" : 5, "marks" : [ 7, 2, 2, 4, 7 ] }
> query = { "marks.0" : { "$gte" : 3, "$lte" : 8 } }
{ "marks.0" : { "$gte" : 3, "$lte" : 8 } }
> c.find( query )
{ "_id" : 2, "marks" : [ 4, 2, 6, 4, 5 ] }
{ "_id" : 4, "marks" : [ 6, 2, 2, 4, 7 ] }
{ "_id" : 5, "marks" : [ 7, 2, 2, 4, 7 ] }
2 Likes

Thanks for your prompt reply. As I already mentioned in my post that I want to use this with $expr in $match aggregation pipeline, instead of find. Thanks again.

Thanks for your prompt reply. I have applied with both $first and $arrayElemAt. Both are working absolutely fine. But why it is not working with dot notation. Thanks again.

Honestly, I don’t know. may be @steevej can help on that

Sorry, I missed the aggregation part. But the same query is also working inside an aggregation $match stage.

> query = { "marks.0" : { "$gte" : 3, "$lte" : 8 } }
{ "marks.0" : { "$gte" : 3, "$lte" : 8 } }
> match = { $match : query }
{ "$match" : { "marks.0" : { "$gte" : 3, "$lte" : 8 } } }
> c.aggregate( [ match ] )
{ "_id" : 2, "marks" : [ 4, 2, 6, 4, 5 ] }
{ "_id" : 4, "marks" : [ 6, 2, 2, 4, 7 ] }
{ "_id" : 5, "marks" : [ 7, 2, 2, 4, 7 ] }
1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.