有可能與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
}
聚合框架可以接近更好的輸出,但只能處理靜態數據,不能「動態」分配未知的鍵名稱。但是,如果你知道會發生,你可以這樣做的:
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"
}
在這兩種情況下,操作是相當瑣碎和真的不考慮「場」的多個值的存在或對它們做什麼。在現實世界彙總術語中,最好堅持所提出的數據模式,而不是試圖將「數據點」表示爲「基本」,因爲這基本上是要求的。但是從這樣一個樣本中確定真正的預期用途是不可能的。
不太確定你在這裏的意思。在這種情況下,確實有三個文檔和一個結果,其中有三個不同的值。但是有什麼意義呢?多於一個事件的一般聚合規則是什麼?簡單地解決上述問題的答案很簡單,但不是很有用。你通常只想保持數據模式而不是改變它。數據點作爲關鍵從來不是一個好主意。 – 2014-10-27 23:15:02
這樣做的目的是運行查詢,然後流式傳輸到csv,其中字段名稱是列標題。另一個有用的目的是將數據水平而不是垂直地顯示在網格中。 – Rob 2014-10-28 16:01:14