2

我有一个Client和一个Group模型。一个客户有很多组。

class Client
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Timestamps

  field ...

  has_many :groups, dependent: :delete

  ...
end

class Group
  ...

  belongs_to :client
end

一个客户有40k组,当我尝试时client.groups,它需要太长时间。我已经等了几分钟,它永远不会结束。

MONGODB (14.2ms) humtl_development['groups'].find({:deleted_at=>nil, "client_id"=>BSON::ObjectId('51b37763218c5a19e0000048')})
MONGODB [DEBUG] cursor.refresh() for cursor 48594378191047181

我在 mongoid 文档中找到了这个。

40k 文件太多了吗?我应该摆脱has_many关系并embeds_many改为使用吗?问题是我的mongoid版本?MongoDB配置?任何建议表示赞赏。

当然我不需要显示所有 40k 组,我需要的是User.where(:group_id.in => client.groups.map(&:id)).

非常感谢。

PS:MongoDB v2.4.3 mongoid v2.7.1 mongo v1.9.2

4

1 回答 1

2

确保您已client_id对文档编制索引,以便快速查找。然后您可以使用distinct(:_id)在数组中获取 40K id。所以您的最终查询将如下所示User.where(:group_id.in => client.groups.distinct(:_id)):这是我能想到的获取 40K id 数组的最有效方法。试试看——它可能会起作用,但正如每个人都已经说过的那样——它不是网络规模的;)

据我所知,您正在尝试获取给定客户端的所有用户,并且您的用户可能通过不同的组关联到多个客户端。为了能够有效地为没有加入的客户查找用户(因为你没有加入 mongoid),你可以在没有反向关系的客户上使用 HABTM。所以我会做以下事情:

class Client
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Timestamps

  field ...

  has_and_belongs_to_many :users
  has_many :groups, dependent: :delete

  ...
end

class User
  has_and_belongs_to_many :clients
end

然后每次将用户关联到组时,请记住将组的客户端添加到用户(user.clients << clientclient.users << user),以便他们彼此了解。不要担心重复,因为 mongoid 使用 Set 所以如果用户和客户端之间的关系已经存在,它不会做任何事情。然后您可以从客户端client.users查找用户:或为多个客户端查找用户:User.where(:client_ids.in => client_ids)

于 2013-09-19T19:36:31.593 回答