我正在使用Mongoose,我有一个包含这样的文档的集合
{
"_id" : 1,
"body" : "[{\"order_id\":\"647936\",\"order_datetime\":\"2015-12-02 11:10:00\"}]",
"user_info" : {
"contact_email" : "test@test.com",
"contact_phone" : "1234567",
},
"type" : "ORDERS",
"version" : 1
}
{
"_id" : 2,
"body" : "[{\"order_id\":\"647936\",\"order_datetime\":\"2015-12-02 11:10:00\"}]",
"user_info" : {
"contact_email" : "test@test.com",
"contact_phone" : "1234567",
},
"type" : "ORDERS",
"version" : 2
}
{
"_id" : 3,
"body" : "[{\"order_id\":\"647936\",\"order_datetime\":\"2015-12-02 11:10:00\"}]",
"user_info" : {
"contact_email" : "test@test.com",
"contact_phone" : "1234567",
},
"type" : "ORDERS",
"version" : 3
}
正如您在body字段中看到的那样,您可以看到order_id,因此相同的order_id可以在多个文档中重复,但版本会有所不同。
我想要的是我想搜索a的最大版本号 给定order_id。
就我而言,它将是3。
我尝试使用像
这样的简单查询myCollection.aggregate([
{ "$match" : { "body.order_id" : 647936 } },
{ "$group": {
"_id" :"version",
"max": { "$max": "version" }
}}
] , function(err, data){
console.log(err);
console.log(data);
});
但结果是
null
[]
**请注意我的mongoose连接工作正常,我可以做一些简单的查询,结果还可以。
答案 0 :(得分:1)
您的数据是此处的问题,因为看起来像结构化文档的内容已存储为字符串:
// Bad bit
"body" : "[{\"order_id\":\"647936\",\"order_datetime\":\"2015-12-02 11:10:00\"}]",
相反,你会想要这个:
// Acutally data and not a string
"body" : [{ "order_id": "647936", "order_datetime": ISODate("2015-12-02 11:10:00.000Z" }],
使用这样的数据,获取最新版本只是对结果进行排序的简单问题,而没有.aggregate()
的开销:
myCollection.find({ "body.order_id": "647936" })
.sort({ "version": -1 }).limit(1).exec(function(err,result) {
})
无需聚合,而且速度要快得多,因为您只需选择具有最新(最大)版本号的文档。
为了“修复”数据,您可以在shell中执行类似“一次性”执行的操作:
var bulk = db.myCollection.initializeOrderedBulkOp(),
count = 0;
// query selects just those "body" elements that are currently a string
db.myCollection.find({ "body": { "$type": 2 } }).forEach(function(doc) {
var fixBody = JSON.parse(doc.body); // Just parse the string
fixBody.forEach(function(el) {
// Fix dates
el.order_datetime = new Date(
Date.parse(el.order_datetime.split(" ").join("T") + "Z")
);
});
// And queue an update to overwrite the "body" data
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "body": fixBody }
});
count++;
// Send every 1000
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.myCollection.initializeOrderedBulkOp(),
}
});
// Send any remaining batched
if ( count % 1000 != 0 )
bulk.execute();
您可能还希望以类似的方式将日期以外的“字符串”转换为数值,并在查询中进行适当更改。