2

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

我该怎么做?

非常感谢!

4

3 回答 3

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

问候!

于 2012-11-11T16:24:29.143 回答
0

您可以使用:

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

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

于 2012-11-07T12:48:02.190 回答
0

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

在 mongo 外壳中

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. 您需要在 gemfile 中进行更改以安装最新的轻便摩托车并运行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 }}})
于 2012-11-07T17:41:40.040 回答