【问题标题】:MongoDB group by type and by dateMongoDB 按类型和日期分组
【发布时间】:2016-03-23 05:03:43
【问题描述】:

我有一个包含一个简单文档的集合来存储impressionsconversions,结构如下:

/* 1 */
{
    "_id" : ObjectId("566f1ef857c1e6dd3123050a"),
    "path_id" : ObjectId("55944c1ebe244fd19cbf510b"),
    "data_type" : "impression",
    "created_at" : ISODate("2015-12-14T19:56:40.100Z"),
    "__v" : 0
}

/* 2 */
{
    "_id" : ObjectId("566f1fc9ac964e6f327c55d6"),
    "path_id" : ObjectId("55944c1ebe244fd19cbf510b"),
    "data_type" : "conversion",
    "created_at" : ISODate("2015-12-14T20:00:09.972Z"),
    "__v" : 0
}

/* 3 */
{
    "_id" : ObjectId("566f2896739f6afa4485f327"),
    "path_id" : ObjectId("562e594315ef3d8c3f05d219"),
    "data_type" : "impression",
    "created_at" : ISODate("2015-12-14T20:37:42.139Z"),
    "__v" : 0
}

/* 4 */
{
    "_id" : ObjectId("566f28e5739f6afa4485f328"),
    "path_id" : ObjectId("562e594315ef3d8c3f05d219"),
    "data_type" : "impression",
    "created_at" : ISODate("2015-12-14T20:39:01.233Z"),
    "__v" : 0
}

我可以按data_type 分组和计数,但我需要做的是按date 分组,然后对data_type 进行计数以获得以下结果:

[
    {
        '_id': 'Y',
        'conversions': 20,
        'impressions': 2703,
        'date': '2015-12-14'
    },
    {
        '_id': 'Z',
        'conversions': 10,
        'impressions': 1703,
        'date': '2015-12-13'
    } 
]

我现在拥有的代码如下,但它仅按data_type 分组。我正在尝试添加一个项目以按日期重新组合,但到目前为止没有运气。

var path_id = new mongoose.Types.ObjectId( req.body.path_id );
var match = {
    'path_id': {
        $eq: path_id
    }
};

var group = {
    '_id': '$data_type',
    'count': {
        '$sum': 1
    }
}

Hit.aggregate( [ {
    $match: match
}, {
    $group: group
} ], function( err, res ) {
    console.log( res );
} );

结果是

POST /api/hits/bypath 200 30ms - 15b
[ { _id: 'conversion', count: 2 },
  { _id: 'impression', count: 2703 } ]

【问题讨论】:

  • 我正在尝试添加一个项目以按日期重新组合是什么意思?预期的结果是什么?

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

要按日期进行嵌套分组,您必须使用 日期聚合运算符 $dateToString

这里是查询

db.hits.aggregate([
    {
      "$project": {
        "created_at": {
          "$dateToString": {
            "format": "%Y-%m-%d",
            "date": "$created_at"
          }
        },
        "data_type": true
      }
    },
    {
      "$group": {
        "_id": {
          "data_type": "$data_type",
          "created_at": "$created_at"
        },
        "count": {
          "$sum": 1
        }
      }
    },
    {
      "$group": {
        "_id": {
          "data_type": "$_id.data_type"
        },
        "data":{ "$addToSet" : { count: "$count", date: "$_id.created_at" } }
      }
    }
  ])

如果要在分组操作之前根据条件进行匹配,请在查询中添加如下

{
  "$match": {
    "path_id": {
      "$eq": "<path_id>"
    }
  }
}

【讨论】:

    【解决方案2】:

    您可以使用Date Aggregation Operators 投影日/月/年字段,然后按它们分组

    {
      "$project": {
        "y": {
          "$year": "$created_at"
        },
        "m": {
          "$month": "$created_at"
        },
        "d": {
          "$dayOfMonth": "$created_at"
        },
        "data_type" : 1
      }
    },
    {
      "$group": {
        "_id": {
          "year": "$y",
          "month": "$m",
          "day": "$d",
          "data_type": "$data_type"
        },
        count: {
          "$sum": 1
        }
      }
    }
    

    并将以这种格式输出:

        "_id": {
          "year": 2015,
          "month": 10,
          "day": 5,
          "data_type": "impression"
        },
        count: 10
    

    然后再次按日期分组以将类型组合到一个文档中

    {
      "$group": {
        "_id": {
          "year": "$_id.year",
          "month": "$_id.month",
          "day": "$_id.day"
        },
        types: {"$push":"$_id.data_type"},
        counters: {"$push":"$count"}
      }
    }
    

    这将导致:

        "_id": {
          "year": 2015,
          "month": 10,
          "day": 5
        },
        types: ["impression", "conversion"]
        counters: [10, 5]
    

    虽然我不确定,但可能有更优雅或更快(1 组)的方式来做到这一点。

    【讨论】:

      猜你喜欢
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2019-06-06
      • 2011-07-07
      • 2015-01-03
      • 2013-11-25
      相关资源
      最近更新 更多