ObjectId is a 12-byte BSON type, constructed using:開發環境:MongoDB Server v2.4.9
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.
目標: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
}
沒有留言:
張貼留言