0

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 ?

1 Answer 1

1

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"}}
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.