我正在尝试重构Mongo查询的结果,以使用属性调用'field'中的值作为结果中的键。
我有一个查询返回我的结果:
[
{
"_id" : ObjectId("544ecbf11972fd515fd6306c"),
"field" : "fieldOne",
"value" : "fieldOneValue"
},
"_id" : ObjectId("544ecbf11972fd515fd6307c"),
"field" : "fieldTwo",
"value" : "fieldTwoValue",
},
{
"_id" : ObjectId("544ecbf11972fd515fd6308c"),
"field" : "fieldThree",
"value" : "fieldThreeValue"
}
]
有没有办法得到这样的结果:
{
fieldOne:fieldOneValue,
fieldTwo:fieldTwoValue,
fieldThree:fieldThreeValue
}
答案 0 :(得分:0)
可以使用mapReduce执行此操作,因为基本上您需要JavaScript处理来生成动态密钥。
映射非常简单:
var mapper = function () {
var obj = {};
obj[this.field] = this.value;
emit(1,obj);
};
并且减速器只是将所有发出的元素与相同的"键"值:
var reducer = function (key,values) {
var reduced = {};
values.forEach(function(value) {
Object.keys( value ).forEach(function(key) {
reduced[key] = value[key];
});
});
return reduced;
};
简单地打电话并获得结果,尽管是在一个非常" mapReduce"因为这就是输出总是如此:
db.threedocs.mapReduce(mapper,reducer,{ out: { inline: 1 } })
{
"results" : [
{
"_id" : 1,
"value" : {
"fieldOne" : "fieldOneValue",
"fieldTwo" : "fieldTwoValue",
"fieldThree" : "fieldThreeValue"
}
}
],
"timeMillis" : 6,
"counts" : {
"input" : 3,
"emit" : 3,
"reduce" : 1,
"output" : 1
},
"ok" : 1
}
聚合框架可以更接近更好的输出,但只能处理静态数据而不能动态地#34;分配未知的密钥名称。但如果你知道会发生什么,你可以这样做:
db.threedocs.aggregate([
{ "$group": {
"_id": null,
"fieldOne": {
"$max": {
"$cond": [
{ "$eq": [ "$field", "fieldOne" ] },
"$value",
0
]
}
},
"fieldTwo": {
"$max": {
"$cond": [
{ "$eq": [ "$field", "fieldTwo" ] },
"$value",
0
]
}
},
"fieldThree": {
"$max": {
"$cond": [
{ "$eq": [ "$field", "fieldThree" ] },
"$value",
0
]
}
}
}},
{ "$project": {
"_id": 0,
"fieldOne": 1,
"fieldTwo": 1,
"fieldThree": 1
}}
])
输出更好:
{
"fieldOne" : "fieldOneValue",
"fieldTwo" : "fieldTwoValue",
"fieldThree" : "fieldThreeValue"
}
在任何一种情况下,操作都相当简单,并没有真正考虑到"字段"的多个值的存在。或者如何处理它们。在现实世界聚合术语中,最好坚持使用所呈现的数据模式,而不是试图表示数据点" as" keys"因为这基本上要求。但是不可能从这样的样本中确定真正的用途是什么。
答案 1 :(得分:0)
使用 MongoDB 4.4(没有检查以前的版本):
db.coll.aggregate($project: {
$arrayToObject:
{$map:
{
input: "$arrayToParse",
as: "this",
in: {
"k":"$$this.field",
"v":"$$this.value"
}
}
}
}
)