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
方法或其别名raw
和results
检索 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
:通过管道读取、发出、缩减和输出的文档数量。input
、emitted
、reduced
、output
:单独计数方法。 请注意,emitted
和reduced
方法的命名与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
方法检索原始结果并从原始结果中获取统计信息。