2014年2月26日 星期三

MongoDB 開發筆記 - Aggregate 之 Group BY Timestamp / GROUP BY ObjectID getTimestamp @ MongoDB Server v2.4.9

上回看文件時,上頭說系統預設 ObjectID(_id) 中,已經有時間戳記了,並且建議不需要額外在儲存一個時間:
ObjectId is a 12-byte BSON type, constructed using:
a 4-byte value representing the seconds since the Unix epoch,
a 3-byte machine identifier,
a 2-byte process id, and
a 3-byte counter, starting with a random value.
開發環境:MongoDB Server v2.4.9
目標:SELECT `timestamp`, count(*) AS count FROM `test` GROUP BY `timestamp`;

儘管 ObjectID 有提供 _id.getTimestamp() 方式存取時間,但是在用 aggregate 時卻無法動態取用($year, $month, $dayOfMonth),如:

mongodb> db.test.aggregate({
$group:{
_id: {
year: { $year: "$_id.getTimestamp()" } ,
month: { $month: "$_id.getTimestamp()" } ,
day: { $dayOfMonth: "$_id.getTimestamp()" }
},
count: {
$sum:1
}
}
})
mongodb> aggregate failed: {
        "errmsg" : "exception: can't convert from BSON type EOO to Date",
        "code" : 16006,
        "ok" : 0
}


看來在 v2.4.9 版的應用時,還是需要建立一個 timestamp 出來,然而 db.collection.update 無法拿 document 自身資料來更新,例如從 ObjectID 抽出時間來用:

mongodb> db.test.update({timestamp: null }, { $set : { timestamp: _id.getTimestamp() } }, {multi:true})
ReferenceError: _id is not defined


需要改用 forEach 來一筆筆更新:

mongodb> db.test.find({timestamp:null}).snapshot().forEach(
function (item) {
item.timestamp = item._id.getTimestamp();
//db.test.save(item);
db.test.update(
# query
{
'_id': item['_id']
},
# update
{
'$set':
{
'timestamp': item['timestamp']
}
},
upsert=False, multi=False
);
}
)


接著終於可以 GROUP BY DATE 了 Orz

mongodb> db.test.aggregate(
{
$group:{
_id: {
year: { $year: "$timestamp" } ,
month: { $month: "$timestamp" } ,
day: { $dayOfMonth: "$timestamp" }
},
count: {
$sum:1
}
}
}
)
{
        "result" : [
                {
                        "_id" : {
                                "year" : 2014,
                                "month" : 2,
                                "day" : 22
                        },
                        "count" : 23
                },
                {
                        "_id" : {
                                "year" : 2014,
                                "month" : 2,
                                "day" : 21
                        },
                        "count" : 15
                },
                {
                        "_id" : {
                                "year" : 2014,
                                "month" : 2,
                                "day" : 20
                        },
                        "count" : 200
                }
        ],
        "ok" : 1
}

沒有留言:

張貼留言