MongoDB mongoid 如果 map 只有一条记录, 就不会去 reduce?

lainuo · 2011年12月05日 · 最后由 lainuo 回复于 2012年02月04日 · 3004 次阅读
  def self.cities
    cities_map = <<MAP
        function() {
          if (typeof this.location !== 'undefined' && this.location !== null)
            emit(this.location, { login: this.login, count: 1 });
        }
MAP

    cities_reduce = <<REDUCE
        function(key, values) {
          var sum = 0;
          var logins = [];
          values.forEach(function(value) {
              sum += value.count;
              logins.push(value.login)
            });
            return { logins: logins, sum: sum };
          };
REDUCE

    self.collection.map_reduce(cities_map, cities_reduce, :out => "mr_results")
  end

结果只有一条记录的香港没有进行 reduce

1.9.2p290 :001 > @cities = User.cities.find().to_a => [{"_id"=>"杭州", "value"=>{"logins"=>["lainuo", "winfield"], "sum"=>2.0}}, {"_id"=>"香港", "value"=>{"login"=>"cersei", "count"=>1.0}}]

虽然说只有一条记录不进行 reduce 可以算是合理, 不过这样结果不大好处理啊, 有没有办法强制进行 reduce 呢?

目前我是这么变通了一下:

    cities_map = <<MAP
        function() {
          if (typeof this.location !== 'undefined' && this.location !== null)
            emit(this.location, { logins: [this.login], count: 1 });
        }
MAP

    cities_reduce = <<REDUCE
        function(key, values) {
          var count = 0;
          var logins = [];
          values.forEach(function(value) {
              count += value.count;
              logins.push(value.logins.pop());
            });
            return { logins: logins, count: count };
          };
REDUCE

不知道有没有更好的办法.

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册