2012-04-16 127 views
0

我使用GridFS來存儲圖像。每個圖像都有一個group_id的元數據,基本上只是定義它們是否屬於同一原始圖像。所以每張圖片都有多種尺寸,group_id就是將相同的圖片組合在一起。MongoDB組由嵌套結果

我想查詢這個,但按group_id分組。所以它會返回一個group_id的數組,每個都有對象的信息(寬度,ID等)。

如果我只是做我想要的記錄發現,這是它的樣子:

[ { _id: 4f871d4adaf6fa492f000001, 
    width: '500', 
    group: '1' }, 
    { _id: 4f871d4adaf6fa492f000004, 
    width: '150', 
    group: '1' }, 
    { _id: 4f871d4bdaf6fa492f000007, 
    width: '100', 
    group: '1' }, 
    { _id: 4f871d4bdaf6fa492f00000a, 
    width: '50', 
    group: '1' }, 
    { _id: 4f871d51daf6faf42e000001, 
    width: '500', 
    group: '2' }, 
    { _id: 4f871d52daf6faf42e000004, 
    width: '150', 
    group: '2' }, 
    { _id: 4f871d53daf6faf42e000007, 
    width: '100', 
    group: '2' }, 
    { _id: 4f871d53daf6faf42e00000a, 
    width: '50', 
    group: '2' } ] 

我看組和MapReduce,並且已經嘗試了各種選項,但似乎沒有任何工作。任何建議或例子都會很棒!

謝謝!

回答

1

一種可能的方式做,這是在新的聚合框架的$組功能(可在2.1.0版本): http://www.mongodb.org/display/DOCS/Aggregation+Framework+-+%24group

> db.images.aggregate({$group:{"_id":"$group", "info":{$push:{"width":"$width", "id":"$_id"}}}}) 
{ 
    "result" : [ 
     { 
      "_id" : "2", 
      "info" : [ 
       { 
        "width" : "500", 
        "id" : ObjectId("4f871d51daf6faf42e000001") 
       }, 
       { 
        "width" : "150", 
        "id" : ObjectId("4f871d52daf6faf42e000004") 
       }, 
       { 
        "width" : "100", 
        "id" : ObjectId("4f871d53daf6faf42e000007") 
       }, 
       { 
        "width" : "50", 
        "id" : ObjectId("4f871d53daf6faf42e00000a") 
       } 
      ] 
     }, 
     { 
      "_id" : "1", 
      "info" : [ 
       { 
        "width" : "500", 
        "id" : ObjectId("4f871d4adaf6fa492f000001") 
       }, 
       { 
        "width" : "150", 
        "id" : ObjectId("4f871d4adaf6fa492f000004") 
       }, 
       { 
        "width" : "100", 
        "id" : ObjectId("4f871d4bdaf6fa492f000007") 
       }, 
       { 
        "width" : "50", 
        "id" : ObjectId("4f871d4bdaf6fa492f00000a") 
       } 
      ] 
     } 
    ], 
    "ok" : 1 
} 
> 

這是不是你所希望達到的效果?

類似的結果也可以用地圖來實現降低運行:

var map = function(){ 
    var info = [{"width":this.width, "id":this._id}]; 
    emit(this.group, {"info":info}); 
} 

var reduce = function(key, values){ 
    var info = []; 
    print(key); 
    print(values.length); 
    for(var v in values){ 
     print(values[v]); 
     for(var i in values[v].info){ 
      if(info.indexOf(values[v].info[i]) == -1){ 
       info.push(values[v].info[i]); 
      }; 
     }; 
    }; 
    return {"info":info}; 
} 

> db.images.mapReduce(map, reduce, {out:{inline:1}}) 
{ 
    "results" : [ 
     { 
      "_id" : "1", 
      "value" : { 
       "info" : [ 
        { 
         "width" : "500", 
         "id" : ObjectId("4f871d4adaf6fa492f000001") 
        }, 
        { 
         "width" : "150", 
         "id" : ObjectId("4f871d4adaf6fa492f000004") 
        }, 
        { 
         "width" : "100", 
         "id" : ObjectId("4f871d4bdaf6fa492f000007") 
        }, 
        { 
         "width" : "50", 
         "id" : ObjectId("4f871d4bdaf6fa492f00000a") 
        } 
       ] 
      } 
     }, 
     { 
      "_id" : "2", 
      "value" : { 
       "info" : [ 
        { 
         "width" : "500", 
         "id" : ObjectId("4f871d51daf6faf42e000001") 
        }, 
        { 
         "width" : "150", 
         "id" : ObjectId("4f871d52daf6faf42e000004") 
        }, 
        { 
         "width" : "100", 
         "id" : ObjectId("4f871d53daf6faf42e000007") 
        }, 
        { 
         "width" : "50", 
         "id" : ObjectId("4f871d53daf6faf42e00000a") 
        } 
       ] 
      } 
     } 
    ], 
    "timeMillis" : 1, 
    "counts" : { 
     "input" : 8, 
     "emit" : 8, 
     "reduce" : 2, 
     "output" : 2 
    }, 
    "ok" : 1, 
} 
> 

希望這將有助於您達到您想要的結果!

+0

是的,那就是結果 - 不幸的是,我在版本2.0.3,無法在這裏更新它。 – dzm 2012-04-17 00:44:40

+0

非常感謝! – dzm 2012-04-17 23:02:20