我是mongo的新手,我的文档看起来像波纹管
{
Abc : [
{ _id : 1 , val : "somevalue" },
{ _id : 2 , val : "new value" },
{ _id : 3 , val : "new new value" }
],
Xyz : [
{ _id : 1 , val : 3456},
{ _id : 2 , val : 7689 },
{ _id : 3 , val : 21342}
],
Ghi : [
{ _id : 1 , val : "somevalue" },
{ _id : 2 , val : "new value" },
{ _id : 3 , val : "new new value" }
],
}
每个字段值应按max _id过滤, 即Abc:“新的新价值”
结果输出应该看起来像
{
_id : 1
Abc : "new new value",
Xyz : 21342,
Ghi : "new new value"
}
注意:db
中的字段可能有所不同或可能不存在答案 0 :(得分:0)
如果您正在使用.find()
查看标准投影,那么“排序”或“展平”数组成员的选项确实不多,但如果元素已经是最快的选项按顺序:
db.test.find({},{
"Abc": { "$slice": -1 },
"Ghi": { "$slice": -1 },
"Xyz": { "$slice": -1 }
})
用它的输出:
{
"_id" : ObjectId("537d876dbeeccb8f75e1ef9a"),
"Abc" : [{ "_id" : 3, "val" : "new new value" }],
"Xyz" : [{ "_id" : 3, "val" : 21342 }],
"Ghi" : [{ "_id" : 3, "val" : "new new value" }]
}
{
"_id" : ObjectId("537d87fe348f6339113e85ae"),
"Abc" : [{ "_id" : 3, "val" : "new new value" }],
"Ghi" : [{ "_id" : 3, "val" : "new new value" }]
}
如果您准备提名所有可能的字段,您可以使用聚合框架执行类似的操作:
db.test.aggregate([
{ "$project": {
"Abc": { "$ifNull": [ "$Abc", [ false ] ] },
"Ghi": { "$ifNull": [ "$Ghi", [ false ] ] },
"Xyz": { "$ifNull": [ "$Xyz", [ false ] ] }
}},
{ "$unwind": "$Abc" },
{ "$unwind": "$Ghi" },
{ "$unwind": "$Xyz" },
{ "$sort": { "Abc._id": -1, "Ghi._id": -1, "Xyz": -1 } },
{ "$group": {
"_id": "$_id",
"Abc": { "$first": "$Abc.val" },
"Ghi": { "$first": "$Ghi.val" },
"Xyz": { "$first": "$Xyz.val" }
}}
])
如果使用$ifNull
运算符不存在该字段以阻止后面的$unwind
语句爆炸,那么基本上会在其中放置[ false ]
数组。里程数可能会有所不同,这是否适合您。它是输出:
{
"_id" : ObjectId("537d876dbeeccb8f75e1ef9a"),
"Abc" : "new new value",
"Ghi" : "new new value",
"Xyz" : 21342
}
{
"_id" : ObjectId("537d87fe348f6339113e85ae"),
"Abc" : "new new value",
"Ghi" : "new new value",
"Xyz" : null
}
或者你可以使用mapReduce做一些更复杂的事情,即使没有实际的减少:
db.test.mapReduce(
function () {
for ( var k in this ) {
if ( k === '_id' )
continue;
this[k].sort(function(a, b) {
if ( a._id < b._id ) {
return -1;
} else if ( a._id > b._id ) {
return 1;
}
return 0;
});
this[k] = this[k].slice(-1)[0].val;
}
var id = this._id;
delete this["_id"];
emit( id, this );
},
function(){},
{
"out": { "inline": 1 }
}
)
哪个有可怕的mapReduce输出,但至少你可以灵活使用文档中的“键”:
"results" : [
{
"_id" : ObjectId("537d876dbeeccb8f75e1ef9a"),
"value" : {
"Abc" : "new new value",
"Xyz" : 21342,
"Ghi" : "new new value"
}
},
{
"_id" : ObjectId("537d87fe348f6339113e85ae"),
"value" : {
"Abc" : "new new value",
"Ghi" : "new new value"
}
}
]
这是一些考虑各自优势和劣势的方法,但却是一种完成工作的方法。