MongoDB组由嵌套结果

问题描述:

我使用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,并且已经尝试了各种选项,但似乎没有任何工作。任何建议或例子都会很棒!

谢谢!

一种可能的方式做,这是在新的聚合框架的$组功能(可在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