Mongodb 当count==1时,MapReduce给出奇数结果

Mongodb 当count==1时,MapReduce给出奇数结果,mongodb,mapreduce,mongoid,Mongodb,Mapreduce,Mongoid,堆栈:MongoDB 2.6.5、Mongoid 3.1.6、Ruby 2.1.1 我正在使用Mongoid做一些MongoDB映射/减少的东西 以下是设置: class User include Mongoid::Document has_many :given_bonuses, class_name: 'Bonus', inverse_of: :giver has_many :received_bonuses, class_name: 'Bonus', inverse_of:

堆栈:MongoDB 2.6.5、Mongoid 3.1.6、Ruby 2.1.1

我正在使用Mongoid做一些MongoDB映射/减少的东西

以下是设置:

class User
  include Mongoid::Document

  has_many :given_bonuses, class_name: 'Bonus', inverse_of: :giver
  has_many :received_bonuses, class_name: 'Bonus', inverse_of: :receiver
end

class Bonus
  include Mongoid::Document


  belongs_to :giver, class_name: 'User', inverse_of: :given_bonuses
  belongs_to :receiver, class_name: 'User', inverse_of: :received_bonuses
end
我正在使用以下Map/Reduce代码:

map = %Q{
  function() {
    emit(this.receiver_id, this.giver_id)
  }
}

reduce = %Q{
  function(key, values) {
    var result = {};
    values.forEach(function(value) {
      if(! result[value]) {
        result[value] = 0;
      }
      result[value] += 1;
    });
    return result;
  }
}

Bonus.all.map_reduce(map, reduce).out(inline: 1)
假设我有两份或更多奖金文件:

> Bonus.count
 => 2
> Bonus.all.to_a
 => [#<Bonus _id: 547612a21dbe8b7859000071, giver_id: "547612441dbe8bf35b000005", receiver_id: "547612531dbe8b4a7200006a">, #<Bonus _id: 547612a21dbe8b78590000f9, giver_id: "547612441dbe8bf35b000005", receiver_id: "547612531dbe8b4a7200006a">]
请注意,
键指向形式为
{“ObjectID”=>Number}
的散列。这是应该的

现在,假设我只有一份奖金文件:

> Bonus.count
 => 1
> Bonus.first
 => #<Bonus _id: 547612a21dbe8b7859000071, giver_id: "547612441dbe8bf35b000005", receiver_id: "547612531dbe8b4a7200006a">
请注意,结果的模式已更改。应该是:

 => [{"_id"=>"547612531dbe8b4a7200006a", "value"=>{"ObjectId(\"547612441dbe8bf35b000005\")"=>1.0}}]
这是怎么回事?

来自:

MongoDB不会为只有 单一值。values参数是一个数组,其元素是 “映射”到键的值对象

在第一种情况下,key
this.receiver\u id
,在其组中有两个文档,因此会为该key调用reduce函数

在第二种情况下,如果
发出的
键在其组中只有一条记录,则根本不会调用reduce函数


因此,您为密钥发出的值(
this.giver_id
)将显示为已发出而不减少,无需进一步减少。

不确定这是否是mongoid问题,但我向他们提出了一个问题:有没有办法强制MongoDB调用
reduce
?如果我必须处理两个不同的结果模式,这会增加很多复杂性。很抱歉我之前的评论,对于一个只有一个文档的组来说,理想情况下没有什么可以减少的。
Reduce
应该不会被处理为输出格式。是的,但是我正在使用超过一百万个文档进行mapreduce。每当某个特定接收器恰好只有一个匹配项时,结果模式就不同于2+匹配项。这意味着我必须编写代码来检查每个结果的模式,而不仅仅是知道所有结果的模式都是相同的。必须有一个更明智的选择。对。
 => [{"_id"=>"547612531dbe8b4a7200006a", "value"=>"547612441dbe8bf35b000005"}]
 => [{"_id"=>"547612531dbe8b4a7200006a", "value"=>{"ObjectId(\"547612441dbe8bf35b000005\")"=>1.0}}]