如何根据从 objectId 中提取的创建日期对 MongoDB 集合进行分组?

Posted

技术标签:

【中文标题】如何根据从 objectId 中提取的创建日期对 MongoDB 集合进行分组?【英文标题】:How can I group my MongoDB collection based on the creation date which I extract form objectId? 【发布时间】:2016-12-31 06:33:09 【问题描述】:

我想在 mongoDB 中使用组聚合,以便根据创建日期对我的文档进行分组。我没有将创建日期保存为字段,但我知道我可以从我的 ObjectId 中提取此日期。所以,我试着写这样的东西:

db.sales.aggregate(
   [
      
        $group : 
           _id :  month: $month: ObjectId("$_id").getTimestamp(), 
                   day: $dayOfMonth: ObjectId("$_id").getTimestamp(), 
                   year: $year: ObjectId("$_id").getTimestamp()
           ,
           averageQuantity:  $avg: "$quantity" ,
           count:  $sum: 1 
        
      
   ]
)

我得到这个错误: 错误:无效的对象 ID:长度: @(shell):5:37

当我写一个特殊的 ObjectId 而不是“$_id”时,它可以工作。例如: ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()

当我有一个日期字段来存储我的创建日期并写下这样的内容时,它也可以工作:

db.sales.aggregate(
   [
      
        $group : 
           _id :  month: $month: "$date", 
                   day: $dayOfMonth: "$date", 
                   year: $year: "$date"
           ,
           averageQuantity:  $avg: "$quantity" ,
           count:  $sum: 1 
        
      
   ]
)

但我想知道,我怎样才能直接使用我的 ObjectId 并获取时间戳

按聚合分组及其相关数据可在此链接中找到: https://docs.mongodb.com/manual/reference/operator/aggregation/group/

但是我用我的自动 mongoDB 生成的 id 替换了这个示例中的简单整数 id 。

【问题讨论】:

Aggregate MongoDB results by ObjectId date的可能重复 【参考方案1】:

getTimestamp() 是一个函数,应该在 javascript 函数中使用。

您需要在查询中更正两件事。一种是获取Id,另一种是使用getTimestamp()函数。

Id 的检索

_id :  month: $month: ObjectId("$_id").getTimestamp(), 
                   day: $dayOfMonth: ObjectId("$_id").getTimestamp(), 
                   year: $year: ObjectId("$_id").getTimestamp()
      

使用月、日和年检索 id 的正确方法

_id :  month: "$_id.month",  day: "$_id.day", year: "$_id.year",

原因:

month 是文档 id 的一部分,因此必须以这种方式检索它。日期和年份类似。

获取时间戳

将结果放入 javascript 循环并使用 getTimestamp() 方法。

db.sales.aggregate(
   [
      
        $group : 
           _id :  month: "$_id.month",  day: "$_id.day", year: "$_id.year",
           averageQuantity:  $avg: "$quantity" ,
           count:  $sum: 1 
        
      
   ]
).forEach(function (doc) 
    
     doc["doc._id.month"]=doc._id.month.getTimestamp();
     doc["doc._id.day"]=doc._id.day.getTimestamp();
     doc["doc._id.year"]=doc._id.year.getTimestamp();
     printjson(doc);
    );

如果你有这样的收藏


        "_id" : 
                "month" : ObjectId("57bd7d3c0da65e3f92328e50"),
                "day" : ObjectId("57bd7d3c0da65e3f92328e51"),
                "year" : ObjectId("57bd7d3c0da65e3f92328e52")
        ,
        "quantity" : 200

使用 javascript 函数执行聚合查询后的结果将给出以下结果


        "_id" : 
                "month" : ObjectId("57bd7d3c0da65e3f92328e50"),
                "day" : ObjectId("57bd7d3c0da65e3f92328e51"),
                "year" : ObjectId("57bd7d3c0da65e3f92328e52")
        ,
        "averageQuantity" : 200,
        "count" : 1,
        "doc._id.month" : ISODate("2016-08-24T10:55:56Z"),
        "doc._id.day" : ISODate("2016-08-24T10:55:56Z"),
        "doc._id.year" : ISODate("2016-08-24T10:55:56Z")

【讨论】:

以上是关于如何根据从 objectId 中提取的创建日期对 MongoDB 集合进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

从对象 id 中提取日期并将其导出到 mongodb 中的 csv

如何根据日期时间约束从另一个数据框中提取行?

mongodb:从 json 查询中的 ObjectID 中提取时间戳

mongodb:从 json 查询中的 ObjectID 中提取时间戳

如何根据多个by-record标准从data.table中提取特定字段?

c#中如何根据一个日期得到这一周的日期