【问题标题】:Mongodb group by and sum and get media with MapMongodb group by and sum and get media with Map
【发布时间】:2016-06-06 22:06:42
【问题描述】:

我的数据库中有这些集合:

项目:

{ "IdUser" : "1", "IdItem" : "1" },
{ "IdUser" : "1", "IdItem" : "2" },
{ "IdUser" : "1", "IdItem" : "3" },
{ "IdUser" : "2", "IdItem" : "4" },
{ "IdUser" : "2", "IdItem" : "5" },
{ "IdUser" : "4", "IdItem" : "6" },
{ "IdUser" : "5", "IdItem" : "7" }

用户

{ "_id" : "1", "DateRegister" : ISODate("2016-03-29T22:00:38.764+0000") },
{ "_id" : "2", "DateRegister" : ISODate("2014-03-29T22:00:38.764+0000") },
{ "_id" : "2", "DateRegister" : ISODate("2015-02-29T22:00:38.764+0000") },
{ "_id" : "4", "DateRegister" : ISODate("2013-01-29T22:00:38.764+0000") },
{ "_id" : "5", "DateRegister" : ISODate("2016-04-29T22:00:38.764+0000") }

我如何才能获得此结果但过滤了 2015 之后注册的用户:

拥有一项的用户:2

拥有两项的用户:1

拥有三个项目的用户:1

我已经尝试过了,但我不知道如何过滤...谢谢!

db.collection.aggregate([
    {
        "$group": {
            "_id": "$IdUser",
            "count": { 
                "$sum": { "$cond": [{ "$gt": [ "$IdItem", null ] }, 1, 0 ] } 
            }            
        }
    },
    {
        "$group": {
            "_id": "$count",
            "users": { "$push": "$_id" }            
        }
    },
    {
        "$project": {
            "_id": 0, 
            "number_of_items": "$_id", 
            "number_of_users": { "$size": "$users" } 
        }
    }
])

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可能希望利用 $lookup 运算符执行 items 集合与 users 集合的连接,然后对 @ 执行 $match 过滤器987654329@字段前管道主要分组操作。

    按照此示例 + 此处指向文档的链接会给您一个想法:

    db.items.aggregate([
        {
            "$lookup": {
                "from": "users",
                "localField": "IdUser",
                "foreignField": "_id",
                "as": "user"
            }
        },
        { "$match": { "user.DateRegister": { "$gt": new Date(2015, 11, 31) } } },
        {
            "$group": {
                "_id": "$IdUser",
                "count": { 
                    "$sum": { "$cond": [{ "$gt": [ "$IdItem", null ] }, 1, 0 ] } 
                }            
            }
        },
        {
            "$group": {
                "_id": "$count",
                "users": { "$push": "$_id" }            
            }
        },
        {
            "$project": {
                "_id": 0, 
                "number_of_items": "$_id", 
                "number_of_users": { "$size": "$users" } 
            }
        }
    ])
    

    如果您的 MongoDB 服务器不支持 $lookup 运算符,您将需要一种解决方法,将操作拆分为不同的集合,即

    • 获取与给定日期范围条件匹配的用户 ID 列表,这可以通过用户集合上的 distinct() 方法和日期查询选项来完成。
    • 在 $match 运算符初始步骤中的项目集合聚合管道中使用该列表。

    以下证明了这一点:

    // use distinct to get the user id's list
    var userIds = db.users.distinct("_id", { "DateRegister": { "$gt": new Date(2015, 11, 31) } })
    
    // perform your aggregation with a filtered collection using the list from the above operations
    db.items.aggregate([
        { "$match": { "IdUser": { "$in": userIds } } },
        {
            "$group": {
                "_id": "$IdUser",
                "count": { 
                    "$sum": { "$cond": [{ "$gt": [ "$IdItem", null ] }, 1, 0 ] } 
                }            
            }
        },
        {
            "$group": {
                "_id": "$count",
                "users": { "$push": "$_id" }            
            }
        },
        {
            "$project": {
                "_id": 0, 
                "number_of_items": "$_id", 
                "number_of_users": { "$size": "$users" } 
            }
        }
    ])
    

    【讨论】:

    • 非常感谢 ;) 它工作得很好......一个评论,IdUser 是一个 ObjectId 是集合用户和 Items 集合中的一个字符串,我该如何解析?
    • 对我来说似乎有点违反直觉;为什么要将 ids 保存为 items 集合中的字符串,而不是将 refs 保存为ObjectIds?无论如何,要解析字符串,您需要在 $lookup 管道之前执行额外的 $project 操作步骤来进行解析:请按照此 answer 获取指导。
    猜你喜欢
    • 2017-05-29
    • 2017-08-08
    • 2010-12-13
    • 1970-01-01
    • 2020-07-21
    • 2020-05-16
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多