0

我正在嘗試重新調整Mongo查詢的結果,以使用屬性調用「字段」中的值作爲結果中的鍵。操縱MongoDB結果動態生成字段名稱

我有一個返回我產生這樣的查詢:

[ 
{ 
    "_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

不太確定你在這裏的意思。在這種情況下,確實有三個文檔和一個結果,其中有三個不同的值。但是有什麼意義呢?多於一個事件的一般聚合規則是什麼?簡單地解決上述問題的答案很簡單,但不是很有用。你通常只想保持數據模式而不是改變它。數據點作爲關鍵從來不是一個好主意。 – 2014-10-27 23:15:02

+0

這樣做的目的是運行查詢,然後流式傳輸到csv,其中字段名稱是列標題。另一個有用的目的是將數據水平而不是垂直地顯示在網格中。 – Rob 2014-10-28 16:01:14

回答

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 
} 

聚合框架可以接近更好的輸出,但只能處理靜態數據,不能「動態」分配未知的鍵名稱。但是,如果你知道會發生,你可以這樣做的:

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" 
} 

在這兩種情況下,操作是相當瑣碎和真的不考慮「場」的多個值的存在或對它們做什麼。在現實世界彙總術語中,最好堅持所提出的數據模式,而不是試圖將「數據點」表示爲「基本」,因爲這基本上是要求的。但是從這樣一個樣本中確定真正的預期用途是不可能的。

+0

mapReduce。謝謝 – Rob 2014-10-28 16:02:50