Menu Docs
Página inicial do Docs
/ / /
Driver Ruby MongoDB
/

Cache de consulta

Nesta página

  • Uso
  • Interações com Fibras
  • Correspondência de query
  • Limites
  • Invalidação de cache
  • Invalidação de cache manual
  • Transações
  • Agregações
  • Coleções do sistema
  • Middleware de cache de query
  • Middleware de rack
  • Middleware de tarefa ativo

O driver Ruby do MongoDB fornece um cache de query integrado. Quando ativado, o cache de query salva os resultados das querys de busca e agregação executadas anteriormente. Quando essas mesmas query são realizadas novamente, o driver retorna os resultados em cache para evitar viagens de ida e volta desnecessárias ao reconhecimento de data center.

O cache de query está desabilitado por padrão. Ele pode ser habilitado no escopo global, bem como dentro do contexto de um bloco específico. O driver também fornece um middleware Rack para ativar o cache de query automaticamente para cada solicitação da web.

Para habilitar o cache de query globalmente:

Mongo::QueryCache.enabled = true

Da mesma forma, para desativá-lo globalmente:

Mongo::QueryCache.enabled = false

Para habilitar o cache de query no contexto de um bloqueio:

Mongo::QueryCache.cache do
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
client['artists'].find(name: 'Flying Lotus').first
#=> Queries the database and caches the result
client['artists'].find(name: 'Flying Lotus').first
#=> Returns the previously cached result
end
end

E para desabilitar o cache de query no contexto de um bloco:

Mongo::QueryCache.uncached do
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
client['artists'].find(name: 'Flying Lotus').first
#=> Sends the query to the database; does NOT cache the result
client['artists'].find(name: 'Flying Lotus').first
#=> Queries the database again
end
end

Você pode verificar se o cache de query está habilitado a qualquer momento ligando para Mongo::QueryCache.enabled?, que retornará true ou false.

O sinalizador de ativação do cache de query é armazenado no armazenamento local de Fibra (usando Thread.current . Isso, em princípio, permite que o estado do cache de query seja por camada, embora isso não seja testado atualmente.

Existem métodos na biblioteca padrão Ruby, como Enumerable#next, que utilizam limitações em sua implementação. Esses métodos não viam o sinalizador de ativação do cache de query quando ele era definido pelos aplicativos e, subsequentemente, não usavam o cache de query. Por exemplo, o código a seguir não utiliza o cache de query, apesar de solicitá-lo:

Mongo::QueryCache.enabled = true
client['artists'].find({}, limit: 1).to_enum.next
# Issues the query again.
client['artists'].find({}, limit: 1).to_enum.next

Reescrever este código para utilizar first em vez de next faria com que ele utilizasse o cache de query:

Mongo::QueryCache.enabled = true
client['artists'].find({}, limit: 1).first
# Utilizes the cached result from the first query.
client['artists'].find({}, limit: 1).first

Uma query será elegível para usar resultados em cache se corresponder à query original que produz os resultados em cache. Duas query são consideradas correspondentes se forem idênticas nos seguintes valores:

  • namespace (o reconhecimento de data center e a collection na qual a query foi realizada)

  • Seletor (para agregações, os estágios do pipeline de agregação)

  • Ignorar

  • Ordenar

  • Projeção

  • Agrupamentos

  • Preocupação de leitura

  • readPreference

Por exemplo, se você executar uma query e, em seguida, executar uma query quase idêntica com uma ordem de classificação diferente, essas queries não serão consideradas correspondentes e a segunda query não usará os resultados em cache da primeira.

When performing a query with a limit, the query cache will reuse an existing cached query with a larger limit if one exists. Por exemplo:

Mongo::QueryCache.cache do
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
client['artists'].find(genre: 'Rock', limit: 10)
#=> Queries the database and caches the result
client['artists'].find(genre: 'Rock', limit: 5)
#=> Returns the first 5 results from the cached query
client['artists'].find(genre: 'Rock', limit: 20)
#=> Queries the database again and replaces the previously cached query results
end
end

O cache de query é limpo em parte ou totalmente em cada operação de gravação. A maioria das operações de gravação limpará os resultados de qualquer query que foram realizadas na mesma collection em que está sendo gravada. Algumas operações limparão todo o cache de query.

As operações a seguir limparão os resultados da query em cache no mesmo reconhecimento de data center e collection (inclusive durante gravações em massa):

  • insert_one

  • update_one

  • replace_one

  • update_many

  • delete_one

  • delete_many

  • find_one_and_delete

  • find_one_and_update

  • find_one_and_replace

As operações a seguir limparão todo o cache de query:

  • agregação com estágios de pipeline $merge ou $out

  • commit_transaction

  • abort_transaction

Você pode limpar o cache da query a qualquer momento com o método a seguir:

Mongo::QueryCache.clear

Isso removerá todos os resultados de query em cache.

As query são armazenadas em cache dentro do contexto de uma transação, mas todo o cache será limpo quando a transação for confirmada ou cancelada.

Mongo::QueryCache.cache do
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
session = client.start_session
session.with_transaction do
client['artists'].insert_one({ name: 'Fleet Foxes' }, session: session)
client['artists'].find({}, session: session).first
#=> { name: 'Fleet Foxes' }
#=> Queries the database and caches the result
client['artists'].find({}, session: session).first
#=> { name: 'Fleet Foxes' }
#=> Returns the previously cached result
session.abort_transaction
end
client['artists'].find.first
#=> nil
# The query cache was cleared on abort_transaction
end
end

Observação

As transações geralmente são realizadas com um nível de referência de leitura "snapshot". Lembre-se de que uma query com uma referência de leitura "snapshot" não pode retornar resultados em cache de uma query sem a referência de leitura "snapshot", portanto, é possível que uma transação não use query em cache anteriormente.

Para entender quando uma query usará um resultado em cache, consulte a seção Correspondência de query .

O cache de query também armazena em cache os resultados de pipelines de agregação. Por exemplo:

Mongo::QueryCache.cache do
Mongo::Client.new([ '127.0.0.1:27017' ], database: 'music') do |client|
client['artists'].aggregate([ { '$match' => { name: 'Fleet Foxes' } } ]).first
#=> Queries the database and caches the result
client['artists'].aggregate([ { '$match' => { name: 'Fleet Foxes' } } ]).first
#=> Returns the previously cached result
end
end

Observação

Os resultados da agregação são limpos do cache durante cada operação de gravação, sem exceções.

O MongoDB armazena informações do sistema em collection que usam o padrão de namespace database.system.* . Essas são chamadas de collection do sistema.

Os dados na collection do sistema podem ser alterados devido a atividades não acionadas pela aplicação (como processos internos do servidor) e como resultado de um reconhecimento de data center emitidos pela aplicação. Devido à dificuldade de determinar quando os resultados em cache para collection do sistema devem ser expirados, as query nas collection do sistema ignoram o cache de consulta.

Você pode ler mais sobre collections do sistema na documentação do MongoDB.

Observação

Mesmo quando a query estiver habilitada, os resultados da query da collection do sistema não serão armazenados em cache.

O driver fornece um middleware Rack que habilita o cache de query para a duração de cada solicitação da web. Abaixo está um exemplo de como habilitar o middleware de cache de query em uma aplicação Ruby on Rails:

# config/application.rb
# Add Mongo::QueryCache::Middleware at the bottom of the middleware stack
# or before other middleware that queries MongoDB.
config.middleware.use Mongo::QueryCache::Middleware

Consulte o guia Rails on Rack para obter mais informações sobre como usar o middleware Rack em aplicativos Rails.

O driver fornece um middleware de tarefa ativa que habilita o cache de query para cada tarefa. Abaixo está um exemplo de como habilitar o middleware de tarefa Active Job de cache de query em uma aplicação Ruby on Rails:

# config/application.rb
ActiveSupport.on_load(:active_job) do
include Mongo::QueryCache::Middleware::ActiveJob
end

Voltar

Atlas Searchgeoespacial

Próximo

GridFS