Mongoid查询缓存 [英] mongoid query caching
问题描述
Rails的ActiveRecord具有称为查询缓存(ActiveRecord :: QueryCache)的功能,该功能可保存SQL查询的结果以保留请求的生命周期.虽然我对实现的内部结构不太熟悉,但我认为它会将查询结果保存在Rack env中的某个位置,该位置在请求结束时被丢弃.
Rails' ActiveRecord has a feature called Query Caching (ActiveRecord::QueryCache) which saves the result of SQL query for the life-span of a request. While I'm not very familiar with the internals of the implementation, I think that it saves the query results somewhere in the Rack env, which is discarded in the end of the request.
Mongoid当前不提供这样的功能,并且由于某些查询隐式地发生(引用),这一事实使情况更加恶化. 我正在考虑实现此功能,我很好奇,应该在何处以及如何挂接Mongoid(或者,也许是mongo驱动程序?)以实现此功能.
The Mongoid, unfortunately, doesn't currently provide such feature, and this is exacerbated by the fact, that some queries occur implicitly (references). I'm considering to implement this feature, and I'm curious, where and how Mongoid (or, perhaps, mongo driver?) should be hooked in order to implement this.
推荐答案
另一个答案显然是错误的.即使mongo会,不仅mongoid或mongo驱动程序都不会缓存查询-它可能仍在网络上的其他计算机上.
The other answer is obviously wrong. Not only mongoid or mongo driver doesn't cache the query, even if mongo would - it still might be on other machine across the network.
我的解决方案是将receive_message包装在Mongo :: Connection中. 优点:一个确定的地方 缺点:反序列化仍然发生
My solution was to wrap the receive_message in Mongo::Connection. Pros: one definite place Cons: deserialization still takes place
require 'mongo'
module Mongo
class Connection
module QueryCache
extend ActiveSupport::Concern
module InstanceMethods
# Enable the selector cache within the block.
def cache
@query_cache ||= {}
old, @query_cache_enabled = @query_cache_enabled, true
yield
ensure
clear_query_cache
@query_cache_enabled = old
end
# Disable the selector cache within the block.
def uncached
old, @query_cache_enabled = @query_cache_enabled, false
yield
ensure
@query_cache_enabled = old
end
def clear_query_cache
@query_cache.clear
end
def cache_receive_message(operation, message)
@query_cache[operation] ||= {}
key = message.to_s.hash
log = "[MONGO] CACHE %s"
if entry = @query_cache[operation][key]
Mongoid.logger.debug log % 'HIT'
entry
else
Mongoid.logger.debug log % 'MISS'
@query_cache[operation][key] = yield
end
end
def receive_message_with_cache(operation, message, log_message=nil, socket=nil, command=false)
if query_cache_enabled
cache_receive_message(operation, message) do
receive_message_without_cache(operation, message, log_message, socket, command)
end
else
receive_message_without_cache(operation, message, log_message, socket, command)
end
end
end # module InstanceMethods
included do
alias_method_chain :receive_message, :cache
attr_reader :query_cache, :query_cache_enabled
end
end # module QueryCache
end # class Connection
end
Mongo::Connection.send(:include, Mongo::Connection::QueryCache)
这篇关于Mongoid查询缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!