Mongoid查询缓存 [英] mongoid query caching

查看:107
本文介绍了Mongoid查询缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆