2012-03-08 28 views
2

我正在使用Perl v5.12和MongoDB包v0.45。如何使用Perl MongoDB包對Mongo副本上的MapReduce

我想運行一個MapReduce作業來創建一個新的集合,然後我將爲之後創建一個遊標。 我的另一個願望是,這項工作運行在副本上,而不是主人。

如perl文檔中所定義,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的這個問題呢? 你成功了嗎? 如果是這樣,請分享您是如何做到的。

回答

2

在輔助設備上執行Map/Reduce操作時,結果必須以內聯方式返回。輸出必須與「結果」對象一起返回,並且不能寫入磁盤,因爲不能寫入副本。以這種方式輸出結果時,結果集的最大值爲16MB。在Map Reduce文檔的「輸出選項」部分的「{inline:1}」項目下有一個註釋。 http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions

+0

我擔心返回內聯結果不會隨着數據集的不斷增長而擴展。是否有一個設置可以在從站中創建新的集合?這樣,MapReduce函數可以成功完成? – 2012-03-08 19:28:09

+0

原諒延遲迴復。不幸的是,目前沒有辦法強制寫入中學。一種可能的解決方法是停止輔助,將mongod作爲獨立進程在不同的端口號上啓動(這很重要,所以不會被其他RS成員看到),執行Map-Reduce操作,將集合複製到需要的位置,然後停止獨立的mongod進程並將其作爲副本集的成員重新啓動。 – Marc 2012-03-16 23:22:19

+0

如果您正在使用主從複製(而不是副本集),則可以強制寫入從機。主從已被棄用,但可在此處找到文檔:http://www.mongodb.org/display/DOCS/Master+Slave – Marc 2012-03-16 23:24:44