微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby-on-rails – MongoDB – Mongoid map减少基本操作

我刚刚开始用MongoDB和mongoid.
我遇到的最大的问题是理解地图/减少功能,以便能够做一些非常基本的分组等等.

我有这样的模型:

class Person
  include Mongoid::Document
  field :age,type: Integer
  field :name
  field :sdate
end

那个模型会产生像这样的对象:

#<Person _id: 9xzy0,age: 22,name: "Lucas",sdate: "2013-10-07">
#<Person _id: 9xzy2,age: 32,name: "Paul",sdate: "2013-10-07">
#<Person _id: 9xzy3,age: 23,name: "Tom",sdate: "2013-10-08">
#<Person _id: 9xzy4,age: 11,name: "Joe",sdate: "2013-10-08">

有人可以展示如何使用mongoid map reduce来获取由sdate字段分组的那些对象的集合?并获得那些共享相同日期字段的年龄之和?

我知道这个:http://mongoid.org/en/mongoid/docs/querying.html#map_reduce
但不知何故,这将有助于将其应用于一个真实的例子.该代码在哪里,在我想的模型中,是需要的范围等.

我可以用mongoid进行简单的搜索,获取数组并手动构造我需要的任何东西,但是我猜这个map reduce就是这样的.我想象这些在类的页面上提到的这些js函数被提供给在内部进行这些操作的数据库.从活跃记录来看,这些新概念有点奇怪.

我在Rails 4.0,Ruby 1.9.3,Mongoid 4.0.0,Heroku(mongolab)上的MongoDB 2.4.6,虽然我有本地2.0,我应该更新.

谢谢.

解决方法

http://mongoid.org/en/mongoid/docs/querying.html#map_reduce为例,并根据您的情况进行调整,并补充说明.
map = %Q{
  function() {
    emit(this.sdate,{ age: this.age,name : this. name }); 
      // here "this" is the record that map
      // is going to be executed on
  }  
}

reduce = %Q{
  function(key,values) {   
           // this will be executed for every group that
           // has the same sdate value
    var result = { avg_of_ages: 0 };
    var sum = 0;    // sum of all ages
    var totalnum = 0  // total number of people
    values.forEach(function(value) {
      sum += value.age;    
    });
    result.avg_of_ages = sum/total   // finding the average
    return result;
  }
}

results = Person.map_reduce(map,reduce) //You can access this as an array of maps

first_average = results[0].avg_of_ages

results.each do |result|
   // do whatever you want with result
end

虽然我建议你使用聚合,而不是映射减少这样一个简单的操作.这样做的方式如下:

results = Person.collection.aggregate([{"$group" => { "_id" => {"sdate" => "$sdate"},"avg_of_ages"=> {"$avg" : "$age"}}}])

并且结果将几乎与地图缩小相同,您将编写的代码少得多.

原文地址:https://www.jb51.cc/ruby/266509.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐