2

我正在从事一个个人项目,在该项目中,我需要按四舍五入的日期对我的所有对象进行分组,直到同一小时。问题是我不想聚合一些东西。

我在 mongodb 中有以下格式的数据存储

{ 
   "_id" : ObjectId("4d663451d1e7242c4b68e000"), 
   "date" : "Mon Dec 27 2010 18:23:22 GMT+0000 (UTC)", 
   "name" : "james"
}, { 
    "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
    "date" : "Mon Dec 27 2010 18:47:53 GMT+0000 (UTC)", 
    "name" : "bond", 
}, { 
    "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
    "date" : "Mon Dec 27 2010 21:51:23 GMT+0000 (UTC)", 
    "name" : "bruce", 
}

我正在寻找以下格式的结果

{
   "rounded_date" : "Mon Dec 27 2010 18:00:00 GMT+0000 (UTC)",
   "items" : [ { 
           "_id" : ObjectId("4d663451d1e7242c4b68e000"), 
           "date" : "Mon Dec 27 2010 18:23:22 GMT+0000 (UTC)", 
           "name" : "james"
       }, { 
           "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
           "date" : "Mon Dec 27 2010 18:47:53 GMT+0000 (UTC)", 
           "name" : "bond", 
       }
   ]
}, {
    "rounded_date": Mon Dec 27 2010 21:00:00 GMT+0000 (UTC),
    "items" : [ { 
            "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
            "date" : "Mon Dec 27 2010 21:51:23 GMT+0000 (UTC)", 
            "name" : "bruce", 
        }
    ]
}

谢谢你的帮助。

4

2 回答 2

4

这看起来像是聚合框架(mongoDB 2.2 中的新功能)的一个很好的候选者,唯一需要注意的是您目前无法动态创建新日期,但您可以从日期中提取所需的数据并按其分组。

请参见以下示例:

# Load the sample data
db.datetest.save({ 
   "_id" : ObjectId("4d663451d1e7242c4b68e000"), 
   "date" : ISODate("2010-12-27T18:23:22Z"),
   "name" : "james"
});

db.datetest.save({ 
    "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
    "date" : ISODate("2010-12-27T18:47:53Z"),
    "name" : "bond", 
});

db.datetest.save({ 
    "_id" : ObjectId("4d6634514cb5cb2c4b69e001"), 
    "date" : ISODate("2010-12-27T21:51:23Z"),
    "name" : "bruce", 
});

现在执行聚合 - 首先将文档重新投影为有用的格式。

db.datetest.aggregate(
    {$project: {
        hour: {0: {"$year": "$date"},
               1: {"$month": "$date"},
               2: {"$dayOfMonth": "$date"},
               3: {"$hour": "$date"}},
        item: {
            _id: "$_id",
            date: "$date",
            name: "$name"
        }
    }},
    {$group: {
        _id: "$hour",
        items: {$push: "$item"}
    }}
)

聚合解释:

  1. 在这里,我们创建一个hour子文档,其中包含从日期中提取的年、月、日和小时。我们还创建了一个item子文档,我们将在 group by 中使用它。
  2. 分组hour并将所有item文档推送到一个items数组中。

结果如下:

{
  "result" : [{
    "_id" : { "0" : 2010, "1" : 12, "2" : 27, "3" : 21 },
    "items" : [
      {
        "date" : ISODate("2010-12-27T21:51:23Z"),
        "name" : "bruce"
      }
    ]}, {
    "_id" : {"0" : 2010, "1" : 12, "2" : 27, "3" : 18},
    "items" : [{
        "date" : ISODate("2010-12-27T18:23:22Z"),
        "name" : "james"
      }, {
        "date" : ISODate("2010-12-27T18:47:53Z"),
        "name" : "bond"
      }
    ]}
  ],
  "ok" : 1
}
于 2012-09-07T09:13:38.817 回答
0

我找到了另一个解决方案:

db.collection.group({
    cond: {'public': true},
    keyf: function(doc) {
        var date = doc.when
        date.setMinutes(0,0,0);
        return {'date' : date};
    },
    initial: { items:[] },
    reduce: function(doc, out) { out.items.push(doc); }
});

问题是使用 groupby 后无法对某些内容进行排序。我想我必须在客户端这样做。

于 2012-09-07T13:45:38.150 回答