我有一组下一个对象:
{
"_did": "213412323234",
"metadata": [
{
"id": "Language",
"value": "EN"
},
{
"id": "City",
"value": "New York"
},
{
"id": "Gender",
"value": "Male"
}
]
}
在使用了一些管道运算符(也许是$ project)之后,我期待这样的事情:
{
"id": "213412323234",
"metadata": {
"Language": "EN",
"City": "New York",
"Gender": "Male"
}
}
答案 0 :(得分:3)
如果已知metadata
字段中元素的位置和嵌入式文档的键,则可以使用聚合。
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"
}
}
}
])
结果:
{ "_id" : "213412323234", "metadata" : { "Language" : "EN", "City" : "New York", "Gender" : "Male" } }
如果上述两个前提条件中的任何一个未知,您可以使用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"}
})
结果:
> db.foobar.find()
{ "_id" : "213412323234", "value" : { "Language" : "EN", "City" : "New York", "Gender" : "Male" } }
请注意,密钥已更改为value
而非元数据。可以使用$project
aggregation
集合中的foobar
轻松修复此问题。
答案 1 :(得分:1)
根据this功能请求及其解决方案,将为此功能添加新功能 - 名为db.foo.aggregate([
{$project: {
metadata: {
$arrayToObject: {
$map: {
input: "$metadata",
as: "pair",
in: ["$$pair.id", "$$pair.value"]
}
}
}
}}
])
的功能。
AddHours
但此刻,没有解决方案。我建议你改变你的数据结构。据我所知,有许多功能请求标记为 Major ,但多年来都没有。
答案 2 :(得分:1)
尝试此查询脚本
var results = db.meta.aggregate([{
$project: {
id: "$_did",
_id: 0,
keys: "$metadata.id",
values: "$metadata.value"
}
}])
function object(keys, values) {
var obj = {};
for (var index in keys) {
obj[keys[index]] = values[index];
}
return obj;
}
results = results.map(function (res) {
return {
id: res.id,
metadata: object(res.keys, res.values)
}
})