我有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 docs中找到了this。
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
答案 0 :(得分: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 << client
或client.users << user
),以便彼此了解。不要担心重复,因为mongoid正在使用Set,所以如果用户和客户端之间的关系已经存在,它就不会做任何事情。然后,您可以从客户端查找用户:client.users
或查找多个客户的用户:User.where(:client_ids.in => client_ids)