Vasu
Vasu

Reputation: 22402

Mongodb embedded document - aggregation query

I have got the below documents in Mongo database:

db.totaldemands.insert({ "data" : "UKToChina", "demandPerCountry" : 
 { "from" : "UK" , to: "China" , 
   "demandPerItem" : [ { "item" : "apples" , "demand" : 200 }, 
   { "item" : "plums" , "demand" : 100 }
] } });

db.totaldemands.insert({ "data" : "UKToSingapore", 
"demandPerCountry" : { "from" : "UK" , to: "Singapore" , 
"demandPerItem" : [ { "item" : "apples" , "demand" : 100 }, 
  { "item" : "plums" , "demand" : 50 }
] } });

I need to write a query to find the count of apples exported from UK to any country.

I have tried the following query:

db.totaldemands.aggregate(
{ $match : { "demandPerCountry.from" : "UK" ,  
  "demandPerCountry.demandPerItem.item" : "apples" } },
  { $unwind : "$demandPerCountry.demandPerItem" },
  { $group : { "_id" : "$demandPerCountry.demandPerItem.item", 
  "total" : { $sum : "$demandPerCountry.demandPerItem.demand" 
  } } }
);

But it gives me the output with both apples and plums like below:

{ "_id" : "apples", "total" : 300 }
{ "_id" : "plums", "total" : 150 }

But, my expected output is:

 { "_id" : "apples", "total" : 300 }

So, How can I modify the above query to return only the count of apples exported from UK ? Also, is there any other better way to achieve the output without unwinding ?

Upvotes: 0

Views: 45

Answers (1)

notionquest
notionquest

Reputation: 39186

You can add another $match to get only apples.

As you have embedded document structure and performing aggregation, $unwind is required here. The alternate option could be map and reduce. However, unwind is most suitable here.

If you are thinking about performance, unwind shouldn't cause performance issue.

db.totaldemands.aggregate(
{ $match : { "demandPerCountry.from" : "UK" ,  
  "demandPerCountry.demandPerItem.item" : "apples" } },
  { $unwind : "$demandPerCountry.demandPerItem" },
  { $group : { "_id" : "$demandPerCountry.demandPerItem.item", 
  "total" : { $sum : "$demandPerCountry.demandPerItem.demand" 
  } } },
  {$match : {"_id" : "apples"}}
);

Upvotes: 1

Related Questions