2014-12-31 58 views
1

我有項目的集合,分組文檔中使用蒙戈聚集

[ a, b, c, d ]

而且我想他們在對等組,

[ [ a, b ], [ b, c ], [ c, d ] ]

計算原始集合中每個項目之間的差異,但該部分是使用多種技術解決的,例如this question中的技術。

我知道這可能與地圖縮小,但我想知道是否有可能與聚合。

編輯:下面是一個例子,

項目的集合;每個項目都是一個實際的文檔。

[ 
    { val: 1 }, 
    { val: 3 }, 
    { val: 6 }, 
    { val: 10 }, 
] 

分組版本:

[ 
    [ { val: 1 }, { val: 3 } ], 
    [ { val: 3 }, { val: 6 } ], 
    [ { val: 6 }, { val: 10 } ] 
] 

產生的集合(或聚合的結果):

[ 
    { diff: 2 }, 
    { diff: 3 }, 
    { diff: 4 } 
] 
+2

您是否可以在收藏中包含示例文檔? 'a','b'代表集合中的文檔,還是它們在文檔字段中的值?它還取決於您想要將這些記錄分組的參數。 – BatScream

+0

@BatScream,我已經添加了一個例子。基本上,'a'和'b'是集合中的文檔。我還添加了最終結果; (不是分組)。我也應該添加它。 – dashersw

+0

我認爲現在可以使用Mongo 3.2'$ lookup'操作符來實現 – RafaelCaballero

回答

4

這是什麼,只是不能與聚合框架來完成,而只有當前可用於此類操作的MongoDB方法是mapReduce。

原因是聚合框架沒有辦法引用管道中的任何其他文檔而不是目前的文檔。這實際上也適用於「分組」流水線階段,因爲即使事物分組在「關鍵」上,您也不能真正以您想要的方式處理單個文檔。

另一方面MapReduce有一個功能可以讓你在這裏做你想做的事情,它甚至不與聚合「直接」相關。事實上,所有階段都具有「全局範圍變量」的能力。並且有一個「變量」基本上「存儲最後一個文件」是您需要達到您的結果。

所以這是很簡單的代碼,並且在事實上沒有「還原」要求:

db.collection.mapReduce(
    function() { 
     if (lastVal != null) 
     emit(this._id, this.val - lastVal); 
     lastVal = this.val; 
    }, 
    function() {}, // mapper is not called 
    { 
     "scope": { "lastVal": null }, 
     "out": { "inline": 1 } 
    } 
) 

其中大部分給你一個結果是這樣的:

{ 
    "results" : [ 
      { 
        "_id" : ObjectId("54a425a99b8bcd6f73e2d662"), 
        "value" : 2 
      }, 
      { 
        "_id" : ObjectId("54a425a99b8bcd6f73e2d663"), 
        "value" : 3 
      }, 
      { 
        "_id" : ObjectId("54a425a99b8bcd6f73e2d664"), 
        "value" : 4 
      } 
    ], 
    "timeMillis" : 3, 
    "counts" : { 
      "input" : 4, 
      "emit" : 3, 
      "reduce" : 0, 
      "output" : 3 
    }, 
    "ok" : 1 
} 

這真的只是撿「東西獨特的「作爲發射的價值而不是任何特定的東西,因爲所有這些都是真正做的是不同文件之間的價值差異。

全局變量通常是解決這些類型的「配對」聚合或產生「運行總數」的解決方案。現在,聚合框架無法訪問全局變量,即使它可能是一個很好的事情。 mapReduce框架擁有它們,所以說它們也應該可用於聚合框架也許是公平的。

現在他們雖然不是,所以堅持mapReduce。

+0

我想在這裏再補充一點,在小組階段,一個文檔不能成爲兩個不同組的一部分,而不是什麼OP示例描述。 – BatScream

+0

喜歡答案+1 – Disposer