我有一个MongoDB数据库,其中包含一个包含过滤字段的文档。文件如下:
{
"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name1",
"filter": "facebook"
} {
"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name2",
"filter": "twitter"
}
{
"_id": ObjectId("503208f5b5db0135387d9249"),
"name": "name3",
"filter": "twitter"
}
我想按类型计算。这个例子应该是这样的:
facebook => 1, twitter => 2
使用ruby代码,计数非常慢。
过滤器是一个String,可以是任何东西。 E.g:
{facebook : 1203, twitter : 201, wherever : 200, othertype : 400}
我正在使用mongo mapper(ruby驱动程序)。
============== 编辑3
最后它正在发挥作用。这是ruby驱动程序的代码:
def map
'function(){
emit(this.plataforma, 1);
}'
end
def reduce
'
function(prev, current) {
var n = 0;
current.forEach(function(v){
n+=v;
});
return n;
}'
end
def build
Mention.collection.map_reduce(map, reduce, :query => {})
end
答案 0 :(得分:0)
我问了这个问题,但没有任何答案。 因此,如果您只有2种过滤器可能性:facebook和twitter,您可以使用两个查询执行此操作:
db.yourcollection.count({
'filter' : 'facebook'
})
这将使你返回1
db.yourcollection.count({
'filter' : 'twitter'
})
这将使你返回2
答案 1 :(得分:0)
这类似于:http://cookbook.mongodb.org/patterns/count_tags/
它在哪里展示了如何像这样运行MR:
var map = function(){
emit(this.filter,1);
}
var reduce = function(previous,current){
var count = 0;
for (index in current) {
count += current[index];
}
return count;
}
然后将输出到另一个集合(或内联,如果需要)格式的文档:
{
_id: facebook,
value: 1,
_id: twitter,
value: 2
}
这是用MongoDBs控制台语言编写的,即JS。 MongoDB有一个内置的JavaScript解析器(spidermonkey),可以解析MR函数。从Ruby中你可以像这样封装你的函数:
map = BSON::Code.new "function() { emit(this.filter, 1); }"
然后像这样运行MR:
col.map_reduce(map, reduce,
{
:out => 'summary_collection',
:raw => true
}
)
然后,您只需通过提供字符串表示形式_id
来查询该过滤器的摘要集合,或者执行简单的find()
即可获得所有结果。
答案 2 :(得分:0)
如果你说过滤器可以是任何东西 - 你应该使用mapreduce。 http://www.mongodb.org/display/DOCS/MapReduce
这是一个有效的代码,将它放在mongo控制台中,然后将其转换为ruby。
首先创建地图功能:
var map = function(){
emit(this.filter, 1);
}
减少功能:
var reduce = function(key, value){
var n = 0;
value.forEach(function(v){
n+=v;
});
return n;
};
因为您使用的是旧版本的mongo,所以您必须执行以下操作:
res = db.runCommand({
'mapreduce' : 'YOURCOLLECTION',
'map' : map,
'reduce' : reduce,
'out' : 'tmp'
});
db.tmp.find();
这会让你回头
{'_id' : 'facebook', 'value' : 1},
{'_id' : 'twitter', 'value' : 2}