mongoid 查询缓存

问题描述 投票:0回答:4

Rails 的 ActiveRecord 有一个称为查询缓存 (ActiveRecord::QueryCache) 的功能,它可以在请求的生命周期内保存 SQL 查询的结果。虽然我不太熟悉实现的内部结构,但我认为它将查询结果保存在 Rack env 中的某个位置,该结果在请求结束时被丢弃。

不幸的是,Mongoid 目前不提供此类功能,并且某些查询隐式发生(引用)这一事实加剧了这种情况。 我正在考虑实现这个功能,我很好奇,为了实现这个功能,应该在哪里以及如何连接 Mongoid(或者也许是 mongo 驱动程序?)。

ruby ruby-on-rails-3 caching mongoid rack
4个回答
15
投票
Mongoid 有缓存,如下所述

http://mongoid.org/en/mongoid/docs/extras.html

MongoDB本身也具有缓存能力:

http://www.mongodb.org/display/DOCS/Caching

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

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

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

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

顺便说一句:如果您确实想在应用程序内缓存结果,您可以尝试

Rails.cache

 或其他缓存 gem 作为解决方法。


7
投票
另一个答案显然是错误的。不仅 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)
    

3
投票
好的,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 应用程序中的中间件。 (阿瑟·内维斯)

对于轨道:

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

    

2
投票
Mongoid 4.0+ 现在有一个 QueryCaching 模块:

http://www.rubydoc.info/github/mongoid/mongoid/Mongoid/QueryCache

您可以通过像这样包装您的查找来在查找中使用它:

QueryCache.cache { MyCollection.find("xyz") }
    
© www.soinside.com 2019 - 2024. All rights reserved.