【问题标题】:MongoDB Aggregate subfields with individual date rangesMongoDB 聚合具有各个日期范围的子字段
【发布时间】:2021-01-19 15:08:47
【问题描述】:

我有一个架构是:

{
"_id" : "12345678",
"action1" : [
    {
        "date" : "2021-01-15",
        "value" : 20
    },
    {
        "date" : "2021-01-14",
        "value" : 16
    }
],
"action2" : [
    {
        "date" : "2021-01-15",
        "value" : 30
    },
    {
        "date" : "2021-01-14",
        "value" : 10
    }
],
"action3" : [
    {
        "date" : "2021-01-15",
        "value" : 40
    },
    {
        "date" : "2021-01-14",
        "value" : 20
    }
],
"action4" : [
    {
        "date" : "2021-01-15",
        "value" : 60
    },
    {
        "date" : "2021-01-14",
        "value" : 40
    }
]

}

现在我想编写一个聚合查询来过滤掉某个日期范围内的计数(过去 7 天、30 天或 90 天)

所以最终的总和应该如下所示:

{
    _id: "12345678"
    action1 : {
        alltime: number,
        last7Days : number,
        last30Days: number,
        last90Days: number
    },
    action2: {
        alltime: number,
        last7Days : number,
        last30Days: number,
        last90Days: number
    },
    action3: {
        alltime: number,
        last7Days : number,
        last30Days: number,
        last90Days: number
    },
    action4: {
        alltime: number,
        last7Days : number,
        last30Days: number,
        last90Days: number
    },
}

我正在尝试使用 $project$match 获取特定 _id 的操作总数

但是如何过滤过去 7 天/30 天/90 天的数据

我的查询如下所示

db.collection.aggregate([
    {
            $project: {
                alltimeAction1: {$sum: "$action1.value"},
                alltimeAction2: {$sum: "$action2.value"},
                alltimeAction3: {$sum: "$action3.value"},
                alltimeAction4: {$sum: "$action4.value"}
            }
    },
    {
        $match: {
            _id: "12345678"
        }
    }
])

mapReduce 是唯一可用的选项吗?

【问题讨论】:

    标签: database mongodb mongodb-query aggregate


    【解决方案1】:
    db.test1.aggregate([
      {
        "$project": {//Reshape actions, you need this as you have dynamic keys
          data: {
            "$objectToArray": "$$ROOT"
          }
        }
      },
      {//Denormalize
        "$unwind": "$data"
      },
      {//Denormalize
        "$unwind": "$data.v"
      },
      {
        "$project": {//Formatting date
          "_id": 1,
          "key": "$data.k",
          "date": {
            "$dateFromString": {
              "dateString": "$data.v.date",
                "format":"%Y-%m-%d"
              
            }
          },
          "value": "$data.v.value"
        }
      },
      {
        "$addFields": {//Getting the conditions ready
          "7Days": {
            $gte:["$date", new Date(new Date().getTime() - (7*24*3600*1000))]
          },
          "30Days": {
            $gte:["$date", new Date(new Date().getTime() - (30*24*3600*1000))]
          }
        }
      },
      {
          $group:{//Grouping them, you can add few more cases
              "_id": "$key",
                      "7days":{
                          $sum:"$value"
                      },
                      "30days":{
                          $sum:"$value"
                      }
                      
                  }
      }
      
    ])
    

    如果您有扁平化架构,其中 actionName 可以通过常量字段名称标识,则无需执行如此复杂的查询。

    【讨论】:

    • 动作名称是常量名称,例如:“openAction”、“closeAction”等。在我上面的问题中,action1、action2 等是常量字段名称
    • 他们有多少?那些是什么?我的意思是扁平结构。
    • 其中有6个,打开、关闭、左、右、滚动、点击,但结构和问题中提到的一样
    猜你喜欢
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多