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,
}
>
希望这将有助于您达到您想要的结果!
是的,那就是结果 - 不幸的是,我在版本2.0.3,无法在这里更新它。 – dzm 2012-04-17 00:44:40
非常感谢! – dzm 2012-04-17 23:02:20