如何使用Perl MongoDB包在Mongo副本上映射MapReduce

时间:2012-03-08 16:50:07

标签: perl mongodb mapreduce master-slave

我正在使用Perl v5.12和MongoDB软件包v0.45。

我想运行一个MapReduce作业来创建一个新的集合,然后我将创建一个光标供以后使用。 我的另一个愿望是这份工作是在副本上运行而不是在主人身上。

正如perl doc中所定义的,MapReduce作业将使用run_command方法执行。 当我执行perl脚本时,我得到:

Mongo error: not master at perlib/Connections.pm line 63.

在阅读有关CPAN的MongoDB文档后,似乎只有一种方法可以让游标从副本中读取。因此该方法不适用于对run_command()的调用。

这是我的代码:

sub get_data {
    my $self = shift;
    my $dbh = shift;
    my $collection_h = shift;   
    my $since_time = $self->get_date_time(shift);
    my $loop_limit = $self->get_data_limit(shift);

    my %data = ();
    my $ctr = 0;

    my $temp_collection='temp_collection';

    my $ids = $dbh->run_command([
         "mapreduce" => $collection_h->{'name'}
        ,"map" => _get_map()
        ,"reduce" => _get_reduce()
        ,"query"    =>  {'to.id' => {'$exists'=>'true'}, 'updatedDate' => { '$gte' => $since_time }}
        ,"out" => $temp_collection      
    ]);

    die ("Mongo error: $ids") unless ref($ids) eq 'HASH';

        # next we create a cursor to this new collection
    my $cfs_h = $dbh->$temp_collection;
    my $id_cursor = $cfs_h->find()->limit($loop_limit);

    $id_cursor->slave_okay(1);
    $id_cursor->immortal(1);
    ...
}

sub _get_map {
    return "function() {emit(this.to.id, 1);}"; 
}

sub _get_reduce {

    return "function(k,vals) {return 1;}"
}

有没有人遇到过尝试在副本上使用MapReduce的问题? 你成功完成了吗? 如果是的话,请你分享一下你是怎么做的。

1 个答案:

答案 0 :(得分:2)

在辅助节点上执行Map / Reduce操作时,必须以内联方式返回结果。输出必须与“results”对象一起返回,并且无法写入磁盘,因为无法写入辅助节点。以这种方式输出结果时,结果集的限制为16MB。在Map Reduce文档的“输出选项”部分的“{inline:1}”子弹下有一个注释。 http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions