简体   繁体   中英

MongoDB aggregate count of items in array across different documents?

Here is my MongoDB collection schema:

company: String
model: String
tags: [String]

I need to aggregate it so I get the following output:

[{
  "_id": {
    "company": "Lenovo",
    "model": "T400"
  },
  "tags": {
    tag: "SomeTag"
    count: 124 // number of times, this tag was found in `Lenovo T400`
  }
}...]

I tried to do the following:

var aggParams = {};
aggParams.push({ $unwind: '$tags' });
aggParams.push({ $group: {
  _id: { company: '$company', model: '$model'  },
  tags: { $push:  { tag: '$tags', count: { $sum: 1 } } },
}});

But I got the following error:

invalid operator '$sum'

What is the right way to do this with aggregation ?

You need to process $unwind on an array in order to deal with it meaninfully in aggregation. Also you adding to an array and "counts" stage a separate. As well an aggregation pipeline in an "array" of arguments itself, and not an object as you have defined:

Model.aggregate([
    { "$unwind": "$tags" },
    { "$group": {
        "_id": {
            "company": "$company",
            "model": "$model",
            "tag": "$tags"
        },
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": { 
            "company": "$_id.company",
            "model": "$_id.model",
         },
         "tags": { "$push": { "tag": "$_id.tag", "count": "$count" }
    }}
], function(err,result) {

})

So two $group stages does the job here. One to sum up the tags within company and model and the other to group on just the "company" and "model" and add the distinct tags and counts to an array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM