简体   繁体   中英

MongoDB aggregation

I have one small problem whit $group, I need get count on all posts tags (get count on tags.post field) from post collection

I use moongose ODM

Post example model:

 var PostSchema = new Schema({
        inc: {
            type: Number
        },
        title: {
            type: String,
            required: true
        },
        description: {
            type: String,
            required: true
        },
        tags:{
            post:[{ type: Schema.Types.ObjectId, ref: 'Tag'}],
            system:[{ type: Schema.Types.ObjectId, ref: 'Tag' }]
        }

    });
    var Post = Mongoose.model('Post', PostSchema, 'posts');

    module.exports = Post;

Tag example model:

var TagSchema = new Schema({

    name: {
        index: { unique: true },
        type: String,
        required: true
    }
});

var Tag = Mongoose.model('Tag', TagSchema, 'tags');

module.exports = Tag;

The result should be something like this:

[
{
 "tags_id":"12345667",
 "count": 4
},
{
 "tags_id":"12345668",
 "count": 3
},
{
 "tags_id":"12345669",
 "count": 2
},
{
 "tags_id":"12345660",
 "count": 1
}
]

In SQL data base it's looked like

SELECT tag_id, COUNT(*) AS count
FROM posts
GROUP BY tag_id;

I have no experience whit MONGODB

This my tried

Post.aggregate([
{
 $match: {
  "tags.post": {
   $ne: []
  }
 },
{
 $lookup:{
  from: "tags",
  localField: "tags.post",
  foreignField: "_id",
  as: "tags"
}
},
{ 
 $group: {
  _id: '$tags._id',
  count: {'$sum':1}
 }
}], function (err, result) {
 if (err) {
  return console.log(err);
 }
  return console.log(result);
});

Result:

[
    {
        "_id": [
            "59ad4cfe454aaf4f46f5dcea",
            "59ad4ff994190a4b8acc6871",
            "59ad4ff994190a4b8acc6872",
            "59ad65bd454aaf4f46f5dd15"
        ],
        "count": 1
    },
    {
        "_id": [
            "59ad65bd454aaf4f46f5dd15"
        ],
        "count": 1
    },
    {
        "_id": [
            "59ae20e19d094c31d3751781"
        ],
        "count": 1
    },
    {
        "_id": [
            "59ad4cfe454aaf4f46f5dcea"
        ],
        "count": 1
    },
    {
        "_id": [
            "59ad4fcb454aaf4f46f5dd02"
        ],
        "count": 1
    }
]

Thanks

Just use one more field in $group like below,

"Count": { "$sum": 1}

This will give you count.

I found solution:

Tag.aggregate([
            {
                $lookup: {
                    from: "posts",
                    localField: "_id",
                    foreignField: "tags.post",
                    as: "posts"
                }
            },
            {
                $unwind: "$posts"
            },
            {
                $group: {_id:"$_id", posts: {$push:"$posts"},name : { $first: '$name' }, size: {$sum:1}}
            },
            {
                $project : { name : 1, size:1 }
            },
            {
                $sort:{size:-1}
            },
            {
                $limit : limit
            }
        ], function (err, result) {
            if (err) {
                return utils.res.error(res, { message: 'Could not fetch all public tags', reason: err, debug: result })
            }
            return utils.res.ok(res, result);
        })

thanks to everyone, if some one has solution batter, please write here i will grateful

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