Reputation: 446
I have a mongo collection (store details) like below...
{
_id: "",
storeName: "store1",
items: [
{
itemName: "mongo",
itemPrice: 20,
itemAvailablity: 100
},
{
itemName: "apples",
itemPrice: 50,
itemAvailablity: 70
}
]
},
{
_id: "",
storeName: "store2",
items: [
{
itemName: "banana",
itemPrice: 10,
itemAvailablity: 30
},
{
itemName: "apple",
itemPrice: 45,
itemAvailablity: 90
}
]
},
{
_id: "",
storeName: "store3",
items: [
{
itemName: "apple",
itemPrice: 10,
itemAvailablity: 30
},
{
itemName: "mongo",
itemPrice: 30,
itemAvailablity: 50
}
]
}
from the above data, I want to get particular item details along with storeName.
If I want to get "mongo" details from all stores then my expected output will be like
[
{
itemName: "mongo",
itemPrice: 20,
itemAvailablity: 100,
storeName: "store1"
},
{
itemName: "mongo",
itemPrice: 30,
itemAvailablity: 50,
storeName: "store3"
}
]
I try with different mongo aggregation queries but I didn't get the output as I expect
can anyone help me out of this
thank you
Upvotes: 2
Views: 2254
Reputation: 3845
db.collection.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
items: {
$elemMatch: {
"itemName": "mongo"
}
}
}
},
// Stage 2
{
$project: {
items: {
$filter: {
input: "$items",
as: "item",
cond: {
$eq: ["$$item.itemName", 'mongo']
}
}
},
storeName: 1
}
},
// Stage 3
{
$addFields: {
"items.storeName": '$storeName'
}
},
]
);
Upvotes: 0
Reputation: 46471
You can use below aggregation
db.collection.aggregate([
{ "$match": { "items.itemName": "mongo" }},
{ "$unwind": "$items" },
{ "$match": { "items.itemName": "mongo" }},
{ "$addFields": { "items.storeName": "$storeName" }},
{ "$replaceRoot": { "newRoot": "$items" }}
])
Or either you can do this way
db.collection.aggregate([
{ "$match": { "items.itemName": "mongo" }},
{ "$addFields": {
"items": {
"$map": {
"input": {
"$filter": {
"input": "$items",
"as": "item",
"cond": { "$eq": ["$$item.itemName", "mongo"]}
}
},
"as": "item",
"in": { "$mergeObjects": ["$$item", { "storeName": "$storeName" }] }
}
}
}},
{ "$unwind": "$items" },
{ "$replaceRoot": { "newRoot": "$items" }}
])
Upvotes: 3
Reputation: 18525
You can achieve this via this aggregation:
db.collection.aggregate([
{
$project: {
storeName: "$$CURRENT.storeName",
items: {
$filter: {
input: "$items",
as: "item",
cond: { $eq: ["$$item.itemName","mongo"] }
}
}
}
},
{ $unwind: "$items" },
{ $addFields: { "items.storeName": "$storeName"} },
{ $replaceRoot: { newRoot: "$items" }}
])
You can see it working here
Upvotes: 3