2

I've been learning mongodb and I'm a little stuck writing a query.

I have the following collection:

{
    _id : 1,
    House: A,
    inventory: [
        {
            place: Kitchen,
            item: fridge
        },
        {
            place: Kitchen,
            item: stove
        },
        {
            place: Kitchen,
            item: TV
        },
        {
            place: Bedroom,
            item: bed
        },
        {
            place: Bedroom,
            item: TV
        }
    ]
},
{
    _id : 2,
    House: B,
    inventory: [
        {
        ....
        }
    ]
},

How would I write a query to return the count of the "places" and "items"? So the output should be like this:
{id: Kitchen, PlaceCount: 3, itemCount: 3} - 3 kitchen,3 items(fridge,stove,TV)
{id: Bedroom, PlaceCount: 2, itemCount: 2} - 2 Bedroom, 2 items(bed,TV)

I need the TV count to be counted within each place.

3
  • Hoi and welcome! You might want to read How do I ask a good question, which enhances the probability for getting a useful answer drastically. You might find ESR's excellent essay How To Ask Questions The Smart Way helpful, too. Commented Sep 8, 2015 at 21:02
  • have you tried db.user.aggregate({ $group : {_id : "$inventory.place", PlaceCount: { $sum : 1 },itemCount: { $sum : 1 } } }, { $match : { } }, { $sort : {_id : 1} }) ? Commented Sep 8, 2015 at 22:54
  • @AlvaroJoao I did, it produces { "_id" : [ "Kitchen", "Kitchen", "Kitchen", "Bedroom", "Bedroom" ], "PlaceCount" : 1, "itemCount" : 1 }, which doesn't make too much sense Commented Sep 8, 2015 at 23:29

1 Answer 1

1

You should go with the Aggregation Pipeline, which allows you to aggregate your data in multiple steps that you provide passing an array.

Your aggregation should be:

db.your_collection.aggregate([
  {$unwind: "$inventory" },
  {$group: { _id: "$inventory.place", placeCount:{$sum : 1}, items : {$push: "$inventory.item"}}},
  {$project: { placeCount: 1, itemsCount : {$size: "$items"}}}
])

Explained:

  1. $unwind producing one result for each of your inventory elements
  2. $group the unwinded inventory elements by place, requiring a count (using $sum) and an array of items (still by place, using $push)
  3. $project the following data of your grouped results from previous step: the placeCount and the size (using $size) of your items array, which is the itemsCount
Sign up to request clarification or add additional context in comments.

1 Comment

Project is the only thing i'm not clear about but i'll read the documentation. thanks for the explanation

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.