文档菜单
文档首页
/ / /
Mongoid
/

Map/Reduce

在本页

  • 执行
  • 原始结果
  • 统计数据

Mongoid 提供了围绕 MongoDB 的 map/reduce 框架的 DSL,用于执行自定义的 map/reduce 作业或简单的聚合。

注意

map-reduce 操作已被弃用。建议使用聚合框架,它比 map-reduce 操作提供更好的性能和可用性,应优先考虑用于新开发。

您可以通过调用map_reduce并提供 map 和 reduce JavaScript 函数来告诉 Mongoid 对一个类或一个标准进行 map/reduce 操作。

map = %Q{
function() {
emit(this.name, { likes: this.likes });
}
}
reduce = %Q{
function(key, values) {
var result = { likes: 0 };
values.forEach(function(value) {
result.likes += value.likes;
});
return result;
}
}
Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)

与标准一样,map/reduce 调用是惰性评估的。除非您迭代结果或对包装器进行调用以强制数据库访问,否则不会对数据库进行任何操作。

Band.map_reduce(map, reduce).out(replace: "mr-results").each do |document|
p document # { "_id" => "Tool", "value" => { "likes" => 200 }}
end

除了 map/reduce,您还必须提供结果的输出位置。如果不提供此信息,将引发错误。有效的 #out 选项有

  • inline: 1:不要将输出存储在集合中。

  • replace: "name":在提供的名称的集合中存储,并覆盖其中存在的任何文档。

  • merge: "name":在提供的名称的集合中存储,并将结果与现有文档合并。

  • reduce: "name":在提供的名称的集合中存储,并减少该集合中所有现有结果。

可以通过 execute 方法或其别名 rawresults 获取 Map/Reduce 执行的结果。

mr = Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)
mr.execute
# => {"results"=>[{"_id"=>"Tool", "value"=>{"likes"=>200.0}}],
"timeMillis"=>14,
"counts"=>{"input"=>4, "emit"=>4, "reduce"=>1, "output"=>1},
"ok"=>1.0,
"$clusterTime"=>{"clusterTime"=>#<BSON::Timestamp:0x00005633c2c2ad20 @seconds=1590105400, @increment=1>, "signature"=>{"hash"=><BSON::Binary:0x12240 type=generic data=0x0000000000000000...>, "keyId"=>0}},
"operationTime"=>#<BSON::Timestamp:0x00005633c2c2aaf0 @seconds=1590105400, @increment=1>}

MongoDB 4.2及以下版本的数据库提供Map/Reduce执行统计信息。从MongoDB 4.4版本开始,Map/Reduce通过聚合管道实现,本节中描述的统计信息不可用。

MapReduce对象上提供了以下方法

  • counts:通过管道读取、发射、减少和输出的文档数量。

  • inputemittedreducedoutput:单独的计数方法。请注意,emittedreduced方法的命名与counts中的哈希键不同。

  • time:Map/Reduce管道执行所需的时间,以毫秒为单位。

以下代码说明了如何检索统计信息

mr = Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)
mr.counts
# => {"input"=>4, "emit"=>4, "reduce"=>1, "output"=>1}
mr.input
# => 4
mr.emitted
# => 4
mr.reduced
# => 1
mr.output
# => 1
mr.time
# => 14

注意

每次调用统计方法都会重新执行Map/Reduce管道。执行结果不会被Mongoid存储。如果需要多个统计信息,请考虑使用execute方法检索原始结果,并从原始结果中获取统计信息。

返回

聚合管道