1
首先,对我的可怜的英语感到抱歉。Mongodb聚合过滤器像子文档
如果我们有以下MongoDB中的文档,
测试数据
{id:1, filter:{f1:'v1-1', f2:'v2-1', f3:['v3-1', 'v3-3']}}
{id:2, filter:{f1:'v1-1', f2:'v2-2', f3:['v3-2', 'v3-3']}}
{id:3, filter:{f1:'v1-1', f2:'v2-2', f3:['v3-1', 'v3-3']}}
准备收集
db.test.drop()
db.test.insert({id:1, filter:{f1:'v1-1', f2:'v2-1', f3:['v3-1', 'v3-3']}})
db.test.insert({id:2, filter:{f1:'v1-1', f2:'v2-2', f3:['v3-2', 'v3-3']}})
db.test.insert({id:3, filter:{f1:'v1-1', f2:'v2-2', f3:['v3-1', 'v3-3']}})
你可以考虑过滤领域为用于过滤功能例如,在许多购物网站上,他们会告诉你有多少LE D电视和现场多少台液晶电视。
我想使用MongoDB来计算每个过滤器选项的多少个文档(包括数组字段中的每个项目),预期结果如下。
预期结果
[
{
_id : { key: 'f1', value: 'v1-1' }, count: 3
},
{
_id : { key: 'f2', value: 'v2-1' }, count: 1
},
{
_id : { key: 'f2', value: 'v2-2' }, count: 2
},
{
_id : { key: 'f3', value: 'v3-1' }, count: 2
},
{
_id : { key: 'f3', value: 'v3-2' }, count: 1
},
{
_id : { key: 'f3', value: 'v3-3' }, count: 3
}
]
这很容易使用的map/reduce得到结果,
的Map/Reduce的解决方案
map = function() {
for (k in this.filter) {
if (this.filter[k] instanceof Array) {
for (j in this.filter[k]) {
emit({ key: k, value: this.filter[k][j]}, 1);
}
} else {
emit({ key: k, value: this.filter[k]}, 1);
}
}
}
reduce = function (k, values) {
result = 0;
values.forEach(function(v) { result += v; });
return result;
}
db.test.mapReduce(map, reduce, {out:{inline:1}})
但与性能问题map/reduce,它不能用于实时查询。如果添加一些查询条件,结果集可能会更改,所以我无法将地图/缩减结果保存到另一个集合中以进行实时查询。
我可以使用聚合框架来计算计数一个过滤器,
只有一个过滤器聚合解决方案
db.test.aggregate(
{$project: {"filter.f2":1, "_id":0}},
{$group: {"_id": {"key": {$ifNull: [null, "f2"]}, "value":"$filter.f2"}, "count" : {$sum: 1}}}
)
[
{
"_id" : { "key" : "f2", "value" : "v2-2" }, "count" : 2
},
{
"_id" : { "key" : "f2", "value" : "v2-1" }, "count" : 1
}
]
但我不知道该怎么做了所有的过滤器选项。任何想法?
很好的答案,谢谢!我使用的是mongodb 2.2,所以我需要在$ group部分使用'_id:{key:“$ key”,values:“$ values”}'。 – jxie