Reputation: 1470
I am trying to fetch an element from an array in the MongoDB. I think the aggregation filter is the right one to apply. But I tried million times already, I still cannot find where is the problem. Could you give me hand?
MongoDB sample data:
{
"_id" : 12,
"items" : [
{
"columns" : [
{
"title" : "hhh",
"value" : 10
},
{
"title" : "hahaha",
"value" : 20
}
]
},
{
"columns" : [
{
"title" : "hiii",
"value" : 50
}
]
}
]
}
My solution:
db.myCollection.aggregate([
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: [ "$$item.columns.title", "hahaha" ]}
}
}
}
}
]).pretty()
My result:
{
"_id" : 15,
"items" : [
{
"columns" : [ ]
},
{
"columns" : [ ]
}
]
}
Expected result:
{
"_id" : 15,
"items" : [
{
"columns" : [
{
"title" : "hahaha",
"value" : 20
}
]
},
{
"columns" : []
}
]
}
I have checked the Mongo reference: https://docs.mongodb.com/manual/reference/operator/aggregation/filter/#example
MongoDB version:3.4.1
Testing environment: Mongo Shell
Upvotes: 3
Views: 3711
Reputation: 61225
You need to use the $map
array operator to $filter
the sub array in your subdocument. Also you should do this in the $addFields
aggregation pipeline stage to automatically include all others fields in the query result if you need them.
You can also replace the $addFields
stage with $project
as you were doing but in this case, you will need to explicitly include all other fields.
let value = "hahaha";
db.coll.aggregate([
{
"$addFields": {
"items": {
"$map": {
"input": "$items",
"as": "item",
"in": {
"columns": {
"$filter": {
"input": "$$item.columns",
"as": "elt",
"cond": { "$eq": [ "$$elt.title", value ] }
}
}
}
}
}
}
}
])
Upvotes: 7