2013-04-14 13 views
0

我得到這個錯誤:紅寶石的蒙戈司機:'刪除':不能轉換符號轉換成String(類型錯誤)

$ ruby mapreduce.rb 
/usr/share/gems/gems/mongo-1.6.4/lib/mongo/collection.rb:618:in `delete': can't convert Symbol into String (TypeError) 
    from /usr/share/gems/gems/mongo-1.6.4/lib/mongo/collection.rb:618:in `map_reduce' 
    from mapreduce.rb:21:in `<main>' 

用下面的代碼:

require 'rubygems' 
    require 'mongo' 

    map = "function() { " + 
    "var keys = [];" + 
    "for (item in this['kg']) { keys.push(item) }" + 
    "emit(keys.sort().join(';'), {count: 1})" + 
    "}" 
    reduce = "function(key, values) { " + 
    "var sum = 0; " + 
    "values.forEach(function(doc) { " + 
    " sum += doc.count; " + 
    "}); " + 
    "return {count: sum}; " + 
    "};" 
    out = "stats" 

    db = Mongo::Connection.new.db("test") 
    coll = db.collection("snps") 

    result = coll.map_reduce(map, reduce, out) 
    result.find.to_a.each do |r| 
puts ['{', r['_id'], ':', r['value']['count'].to_i, '}'].join(" ") 
    end 

具有以下的MongoDB 2.2 0.3。

我做錯了什麼?

回答

1

fine manual

- (Collection, Hash) map_reduce(map, reduce, opts = {})

注意的第三個參數map_reduce應該是一個選項哈希,但你傳遞一個字符串。如果你看看map_reduce源裏面你會看到這一點:

def map_reduce(map, reduce, opts={}) 
    #... 
    raw = opts.delete(:raw) 

所以它最終會調用String#delete用符號參數而不是字符串,String#delete期待有你的錯誤。

您還可以對選擇的文檔中找到這個:

:out (String) — default: nil — a valid output type. In versions of MongoDB prior to v1.7.6, this option takes the name of a collection for the output results. In versions 1.7.6 and later, this option specifies the output type. See the core docs for available output types.

那麼想必你想說:

result = coll.map_reduce(map, reduce, :out => out) 

而且不這樣做:

map = "function() { " + 
    "var keys = [];" + 
    "for (item in this['kg']) { keys.push(item) }" + 
    "emit(keys.sort().join(';'), {count: 1})" + 
    "}" 

使用%Q{...}%q{...}個引號代替:

map = %q{function() { 
    var keys = []; 
    for (item in this['kg']) { keys.push(item) } 
    emit(keys.sort().join(';'), {count: 1}) 
}} 

這是一個更容易閱讀和會少一點,而且容易出錯,當你嵌套了引號。