Ruby mongodb计数相等对象
我有一个MongoDB数据库,其中的文档包含一个过滤器字段。这些文档如下所示:Ruby mongodb计数相等对象,ruby,mongodb,count,Ruby,Mongodb,Count,我有一个MongoDB数据库,其中的文档包含一个过滤器字段。这些文档如下所示: { "_id": ObjectId("503208f5b5db0135387d9249"), "name": "name1", "filter": "facebook" } { "_id": ObjectId("503208f5b5db0135387d9249"), "name": "name2", "filter": "twitter" } { "_i
{
"_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
我想按类型数数。这个例子应该是这样的:
{
"_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代码,计数非常慢
筛选器是一个字符串,可以是任何内容。例如:
{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
我问了这个问题,但没有回答。 因此,如果你只有两种过滤方式:facebook和twitter,你可以通过两个查询来实现:
db.yourcollection.count({
'filter' : 'facebook'
})
这将返回1
db.yourcollection.count({
'filter' : 'twitter'
})
这将返回2个类似于:
其中,它显示了您如何运行这样一个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;
}
col.map_reduce(map, reduce,
{
:out => 'summary_collection',
:raw => true
}
)
然后,它将输出到另一个集合(或内联,如果需要)以下格式的文档:
{
_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:
var map = function(){
emit(this.filter,1);
}
var reduce = function(previous,current){
var count = 0;
for (index in current) {
count += current[index];
}
return count;
}
col.map_reduce(map, reduce,
{
:out => 'summary_collection',
:raw => true
}
)
然后,您可以通过提供字符串表示形式作为
\u id
来查询该筛选器的摘要集合,或者执行一个简单的find()
来获得所有结果。如果您说筛选器可以是任何东西,那么就不应该使用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;
};
减少功能:
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}
您使用的是哪个版本的mongo?您可以将聚合框架与
$match
和$sum
或MR或预聚合一起使用。抱歉,没有阅读您的MongoDB版本。使用该版本,您只能执行映射缩减或预聚合来解决问题。我强烈建议升级您的数据库,因为1.6.3是一个非常旧的版本,缺少很多新功能和更好的查询处理等。筛选器可以是任何内容,它是字符串。筛选器可以是任何内容,它是字符串是的。它可以返回如下任何内容:{facebook:1203,twitter:201,where:200,othertype:400}这是什么代码?我不明白。此查询将运行到200.000多个文档,这会很慢吗?@RodrigoDias此代码不会实时工作。与SQL查询不同,聚合框架可以做到这一点,但不能减少映射。您需要将其输出到摘要集合,并将其存储为缓存,以便每5分钟左右更新一次MR(可能以增量方式)进行读取。当然,您仍然可以进行预聚合,这将解决实时问题,但这意味着您必须更改模式,以便为每个筛选器容纳一个总和字段。@RodrigoDias此代码是JavaScript。这是mongo控制台运行的代码。在Ruby中,您可以将每个函数的代码块包装在BSON::code.new
中,然后调用实际的MR,比如:col.map\u reduce(map,reduce,{:out=>{:inline=>true},:raw=>true})
没错,将map和reduce包装到函数中,并调用提提.collection.map\u reduce(map,reduce,:query=>{})。厚度