获得反嵌套模型mongoid

时间:2012-11-05 18:31:08

标签: ruby-on-rails ruby-on-rails-3 mongoid

2个型号:

Class User
 include Mongoid::Document
 has_many :reports
end

Class Report
 include Mongoid::Document
 belongs_to :user
end

我需要一个查询来让所有用户拥有6个或更多报告,例如:。

Users.where(reports.count > 5)

我使用mongo id 2.4.12

我该怎么做?

非常感谢!

3 个答案:

答案 0 :(得分:1)

好的,由于MongoDB没有连接,因此无法进行此查询。

此问题的修复方法是使用计数器缓存。

第一个选项是使计数器缓存类似于:

class User
  include Mongoid::Document
  field :reports_count, type: Integer
  has_many :reports
end

class Report
  include Mongoid::Document
  belongs_to :user
  after_create do |doc|
    doc.user.inc(:reports_count, 1)
  end
  after_destroy do |doc|
    doc.user.inc(:reports_count, -1)
  end
end

第二个选项(我使用过这个选项)是使用这个gem https://github.com/jah2488/mongoid-magic-counter-cache

对于这个问题:

型号:

class User
 include Mongoid::Document
 field :report_count
 has_many :reports
end

Class Report
 include Mongoid::Document
 include Mongoid::MagicCounterCache
 belongs_to :user
 end

帮助者内部例如:

def users_with_reports_greather_than_5
 users_with_reports_greather_than_5 = []
 for u in User.where(report_count.ne => nil)
  if u.report_count > 5
   users_with_reports_greather_than_5 << u
  end
 end
 return users_with_reports_greather_than_5.count
end

问候!

答案 1 :(得分:0)

您可以使用:

User.collection.find({"reports" => {"$size" => 5}}).count

要获得有5个报告的用户,但要获得报告数超过5的用户,您必须保留一个额外的字段(reports_count),每次添加新报告时该字段都会递增。 您可以在此处提到的嵌入式文档中应用条件: (http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size

答案 2 :(得分:0)

您需要使用mongodb聚合框架来查找获得超过5个报告的用户

在mongo shell中

db.reports.aggregate(
                     // Group by user_id      
                     {$group:{_id:'$user_id',count:{$sum:1}, 

                      // Add the fields to result set along with grouped result
                      name:{$addToSet:'$any_field_you_need_to_return'}}}, 

                     // And return only the users who got greater than 5 reports
                     {$match:{count:{$gt:5}}}) 

<强>更新

Aggregate仅在moped v1.3中引入。您需要在gem文件中进行更改以安装最新的轻便摩托车并运行bundle install

  gem 'moped', :git=>'https://github.com/mongoid/moped.git', :branch => "master"

你可以使用像

这样的聚合
Reports.collection.aggregate(
                  {'$group' => {'_id' => '$user_id','count' => {'$sum' => 1},
                   'name' => {'$addToSet' => '$any_field_you_need_to_return'}}},
                  {'$match' => {'count' => {'$gt' => 5 }}})