我有一个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
我找到了this在 mongoid 文档中。
40k 的文档太多了吗?我应该摆脱 has_many
关系并使用 embeds_many
代替吗?问题是我的mongoid版本? MongoDB 配置?如有任何建议,我们将不胜感激。
当然,我不需要显示所有 40k 个组,我需要的是 User.where(:group_id.in => client.groups.map(&:id))
。
非常感谢。
PS: MongoDB v2.4.3 蒙戈伊德 v2.7.1 蒙戈v1.9.2最佳答案
确保您有client_id
在您的文档中建立索引,因此查找速度很快。那么你可以使用distinct(:_id)
获取数组中的 40K id。所以你的最终查询将如下所示: User.where(:group_id.in => client.groups.distinct(:_id))
。这是我能想到的获取 40K id 数组的最有效方法。尝试一下 - 它可能会起作用,但正如每个人都已经说过的 - 它不是 webscale ;)
据我所知,您正在尝试获取给定客户端的所有用户,并且您的用户可能通过不同的组与多个客户端关联。为了能够有效地查找未加入的客户端的用户(因为您没有加入 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 << client
或 client.users << user
),以便他们相互了解。不用担心重复,因为 mongoid 使用 Set,所以如果用户和客户端之间的关系已经存在,它不会做任何事情。然后就可以从客户端查找用户:client.users
或查找多个客户端的用户:User.where(:client_ids.in => client_ids)
关于ruby-on-rails - Mongoid has_many 关系太慢(永远不会结束) - 40k 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18901071/