mongoid查询缓存

Rails的ActiveRecord有一个名为Query Caching(ActiveRecord :: QueryCache)的function,可以保存请求生命周期的SQL查询结果。 虽然我不太熟悉实现的内部,但我认为它将查询结果保存在Rack env中,在请求结束时将其丢弃。

遗憾的是,Mongoid目前还没有提供这样的function,而且有些查询是隐式发生的(引用),这更加恶化了。 我正在考虑实现这个function,我很好奇,Mongoid(或者,也许是mongo驱动程序?)的位置和方式应该被挂钩以实现它。

Mongoid有缓存,在http://mongoid.org/en/mongoid/docs/extras.html中有描述

MongoDB本身也具有缓存function: http : //www.mongodb.org/display/DOCS/Caching

mongoid缓存额外知道两种不同的情况:缓存模型的所有查询或缓存查询。

Mongoid缓存似乎工作略有不同:它看起来像mongoid委托缓存到mongodb。 (在mongoid的源代码中,我只能找到缓存的选项设置,但没有缓存模块。)

最后会说,缓存一般没有真正的区别 – 在内存中实际上是在内存中! 无论是在应用程序中还是在数据库中。

我不喜欢实现额外的缓存算法,因为这似乎是多余的并且是RAM杀手。

顺便说一句:如果您真的想在应用程序中缓存结果,可以尝试使用Rails.cache或其他缓存gem作为解决方法。

另一个答案显然是错误的。 不仅mongoid或mongo驱动程序不会缓存查询,即使mongo会 – 它仍然可能在网络上的其他计算机上。

我的解决方案是将receive_message包装在Mongo :: Connection中。 优点:一个明确的地方缺点:反序列化仍然发生

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 4支持QueryCache中间件。

只需在application.rb添加中间件即可

 config.middleware.use "Mongoid::QueryCache::Middleware" 

然后获利:

  MOPED: 127.0.0.1:27017 QUERY database=XXX collection=page_variants selector={"$query"=>{"_id"=>BSON::ObjectId('5564dabb6d61631e21d70000')}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil runtime: 0.4397ms MOPED: 127.0.0.1:27017 QUERY database=XXX collection=page_variants selector={"$query"=>{"_id"=>BSON::ObjectId('5564dacf6d61631e21dc0000')}, "$orderby"=>{:_id=>1}} flags=[] limit=-1 skip=0 batch_size=nil fields=nil runtime: 0.4590ms QUERY CACHE database=XXX collection=page_variants selector={"$query"=>{"_id"=>BSON::ObjectId('5564c9596d61631e21d30000')}, "$orderby"=>{:_id=>1}} QUERY CACHE database=XXX collection=page_variants selector={"$query"=>{"_id"=>BSON::ObjectId('5564dabb6d61631e21d70000')}, "$orderby"=>{:_id=>1}} 

资源:

Mongoid更改日志

https://github.com/mongoid/mongoid/blob/master/CHANGELOG.md#new-features-2

3410 Mongoid现在有一个查询缓存,可以用作Rack应用程序中的中间件。 (亚瑟内维斯)

对于Rails:

 config.middleware.use(Mongoid::QueryCache::Middleware) 

Mongoid 4.0+现在有一个QueryCaching模块: http ://www.rubydoc.info/github/mongoid/mongoid/Mongoid/QueryCache

您可以通过包装查找来在查找中使用它,如下所示:

 QueryCache.cache { MyCollection.find("xyz") }