Here is my mongo sample collection,
{
"_id" : ObjectId("62aeb8301ed12a14a8873df1"),
"Fields" : [
{
"FieldId" : "name",
"Value" : [ "test_123" ]
},
{
"FieldId" : "mobile",
"Value" : [ "123" ]
},
{
"FieldId" : "amount",
"Value" : [ "300" ]
},
{
"FieldId" : "discount",
"Value" : null
}
]
}
Here I want to get the matched record like "Fields.FieldId" should be equal to "amount" and "Fields.Value.0" should be greater than 0 or something else given.
Please note down below points,
- "Fields.Value" might null too
- Sometime some of the fields may not appear in the array also
I have tried like below which is not working,
db.form.aggregate([
{
$match:
{
{
$expr: {
$ne: [
{ $filter: {
input: '$Fields',
cond: { if: {$eq:["$$this.FieldId", "amount"]},
then:{$gte: [{$toDouble: "$$this.Value.0"}, 0]} }
}
}, []
]
}
}
}
}])
I don’t want to use $project or $addFields. I just want to do direct $match query. Please suggest me if it is possible.
Thanks in advance,
Mani
2
Answers
Use the
$and
operator to match multiple conditions instead ofif
andthen
.Use the
$first
operator to get the first element from the array.Also, you have additional braces
{}
in the$match
stage that break the query. Remove the additional braces{}
.Demo @ Mongo Playground
One of the canonical ways to perform element-wise checking on an array field would be using
$anyElementTrue
. You can first use$map
to apply your condition(s) on the array to project a boolean array and apply$anyElementTrue
on it.$map
to iterate through theFields
arrayFieldId
is equal toamount
$convert
the string value into double.$and
and compare with 0. If the conversion failed, it will fall back to 0.0 and will not be selected.Mongo Playground