我很难找到明确说明Mongoid在什么时候实际查询Mongo数据库的文档。
假设我有一个叫Projects的模型,它引用了另一个叫Website的模型,如下
class Project
include Mongoid::Document
...
has_one :website
...
end
class Website
include Mongoid::Document
...
belongs_to :project
...
end
如果在我的项目模型中,我有很多方法可以访问网站对象的属性,我的问题是,对Mongodb的实际查询发生在哪一行:
class Project
...
def website_url
@website ||= self.website #Does the query occur here?
website.url # Or does is occur here?
end
我可以预见,在请求对象的实际属性或属性之前推迟查询数据库是非常有益的。然而,我不知道如何测试这一点来为自己确定答案。
感谢
如果您在应用程序中添加日志记录(Moped是Mongoid的底层Mongoid驱动程序):
Moped.logger.level = Logger::DEBUG
Moped.logger = Logger.new($stdout)
您将看到,根据配置的不同,引用文档的属性检索可能会延迟到第一次需要时。
例如,有两个这样的类:
class User
include Mongoid::Document
field :name, type: String
belongs_to :band
end
class Band
include Mongoid::Document
field :name, type: String
field :popularity, type: Integer
has_many :users
end
然后使用类似:
def find_user
query = User.where(:name => 'Johnny')
user = query.first # just the first
puts "Just the user"
puts user.band.name
end
你可能会得到这样的结果:
MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} (2.0020ms)
MOPED: 127.0.0.1:27017 INSERT database=mm collection=users documents=[{"_id"=>"528ebd08cbafedb879000001", "name"=>"Johnny"}] flags=[] (0.0000ms)
MOPED: 127.0.0.1:27017 INSERT database=mm collection=bands documents=[{"_id"=>"528ebd08cbafedb879000002", "name"=>"StackOverflowTo11", "popularity"=>10}] flags=[] (1.0011ms)
MOPED: 127.0.0.1:27017 UPDATE database=mm collection=users selector={"_id"=>"528ebd08cbafedb879000001"} update={"$set"=>{"band_id"=>"528ebd08cbafedb879000002"}} flags=[] (0.0000ms)
MOPED: 127.0.0.1:27017 QUERY database=mm collection=users selector={"$query"=>{"name"=>"Johnny"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (2.0020ms)
Just the user
MOPED: 127.0.0.1:27017 QUERY database=mm collection=bands selector={"$query"=>{"_id"=>"528eb8f3cbafed9682000002"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (16.0160ms)
StackOverflowTo11
如果启用"标识映射"功能和includes
函数调用,则会立即检索(或从缓存中检索)关系。