我收到了这个错误:
$ 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.3。
我做错了什么?
答案 0 :(得分:1)
来自fine manual:
- (收藏,哈希)map_reduce(map,reduce,opts = {})
请注意,map_reduce
的第三个参数应该是一个选项哈希,但是你传递一个字符串。如果您查看map_reduce
来源,您会看到:
def map_reduce(map, reduce, opts={})
#...
raw = opts.delete(:raw)
因此它最终会使用Symbol参数调用String#delete
,而不是String#delete
期待的字符串,并且出现错误。
您还可以在文档中找到选项:
:out
(String
) - 默认值:nil
- 有效的输出类型。在v1.7.6之前的MongoDB版本中,此选项采用输出结果的集合名称。在1.7.6及更高版本中,此选项指定输出类型。有关可用的输出类型,请参阅核心文档。
所以大概你想说:
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})
}}
当您使用嵌套引号时,这样更容易阅读并且噪音更少且容易出错。