Mongodb group by 和 sum 并使用 Map 获取媒体

标签 mongodb mongodb-query aggregation-framework

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

项目:

{ "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 之后注册的用户:

Users with one item: 2

Users with two items: 1

Users with three items: 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" } 
        }
    }
])

最佳答案

您可能想利用$lookup 运算符执行 items 集合与 users 集合的联接,然后执行 $match 在传递主要分组操作之前过滤 DateRegistered 字段。

按照此示例+此处的文档链接将为您提供一个想法:

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 内的项目集合聚合管道中使用该列表 运算符(operator)初始步骤。

以下内容演示了这一点:

// 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" } 
        }
    }
])

关于Mongodb group by 和 sum 并使用 Map 获取媒体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37652643/

相关文章:

MongoDB 聚合计算小时范围内的产品数量

java - MongoTemplate聚合返回 "IllegalArgumentException: Invalid reference"

node.js - Mongoose findByIdAndUpdate 销毁丢失的字段

MongoDB 在事先不知道所有字段的情况下聚合字段

java - MongoDB 数据模型支持每个事件、每个日期范围的唯一访问者

eclipse - 如何使用Mongo为Birt编写表达式?

mongodb - MongoDB 的 fsync 是做什么用的?

java - 使用 java 从 MongoDB 提取时处理空值

javascript - Mongoose 模型的数字类型错误?

java - MongoDB 位置运算符 $ 在 java 中不起作用