Nếu vị trí của các phần tử trong metadata
trường và khóa của các tài liệu nhúng được biết và sau đó bạn có thể sử dụng tính năng tổng hợp.
db.foo.aggregate([
{
$project : {
data : {
"Language" : {
$arrayElemAt : ["$metadata", 0]
},
"City" : {
$arrayElemAt : ["$metadata", 1]
},
"Gender" : {
$arrayElemAt : ["$metadata", 2]
}
}
}
},
{
$project : {
metadata : {
Language : "$data.Language.value",
City : "$data.City.value",
Gender : "$data.Gender.value"
}
}
}
])
Kết quả:
{ "_id" : "213412323234", "metadata" : { "Language" : "EN", "City" : "New York", "Gender" : "Male" } }
Nếu không biết bất kỳ điều kiện tiên quyết nào trong hai điều kiện tiên quyết nêu trên, bạn có thể sử dụng mapReduce
.
db.foo.mapReduce(function () {
var key = this._id;
var metadata = this.metadata;
var valueEmit = {};
for (var i = 0; i < metadata.length; i++) {
valueEmit[metadata[i].id] = metadata[i].value;
}
emit(key, valueEmit)
},
function(key, values) {
// do nothing as it won't be called
// for if value is only one
// for a key
},
{
out : {replace : "foobar"}
})
Kết quả:
> db.foobar.find()
{ "_id" : "213412323234", "value" : { "Language" : "EN", "City" : "New York", "Gender" : "Male" } }
Lưu ý rằng khóa đã được thay đổi thành giá trị value
thay vì siêu dữ liệu. Điều này có thể được khắc phục dễ dàng bằng cách sử dụng $project
trong aggregation
trên foobar
bộ sưu tập.