我刚刚开始用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"}}}])
并且结果将几乎与地图缩小相同,您将编写的代码少得多.