Docs Menu
Docs Home
/ / /
Ruby MongoDB ドライバー
/

クエリ キャッシュ

項目一覧

  • 使用法
  • フィルターとの相互作用
  • クエリ一致
  • 制限
  • キャッシュの無効化
  • 手動キャッシュ無効化
  • トランザクション
  • 集計
  • システム コレクション
  • クエリキャッシュミドルウェア
  • Rack ミドルウェア
  • アクティブなジョブミドルウェア

MongoDB Ruby ドライバーには組み込みのクエリ キャッシュが用意されています。 有効にすると、クエリ キャッシュには以前に実行された検索および集計クエリの結果が保存されます。 When those same queries are performed again, the driver returns the cached results to prevent unnecessary roundtrips to the database.

クエリ キャッシュはデフォルトで無効になっています。 グローバル スコープでも特定のブロックのコンテキスト内で有効にすることもできます。 このドライバーは、ウェブ リクエストごとにクエリ キャッシュを自動的に有効にする Rack ミドルウェアも提供します。

クエリ キャッシュをグローバルに有効にするには、次の手順に従います。

Mongo::QueryCache.enabled = true

同様に、グローバルに無効にするには、次の手順に従います。

Mongo::QueryCache.enabled = false

ブロックのコンテキスト内でクエリ キャッシュを有効にするには、次の手順に従います。

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

また、ブロックのコンテキストでクエリ キャッシュを無効にするには、次の手順に従います。

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

Mongo::QueryCache.enabled?を呼び出すと、クエリ キャッシュが有効になっているかどうかをいつでも確認できます。これにより、 trueまたはfalseが返されます。

クエリ キャッシュ有効化フラグは、スレッド ローカル ストレージ( Thread.current を使用)に保存されます 。これにより、原則として、クエリ キャッシュの状態はフィルターごとになりますが、現在はテストされていません。

Ruby の標準ライブラリには、Enumerable#next のようにフィルターを 使用 するメソッドがあります 実装に含まれます。これらのメソッドでは、アプリケーションによって設定されているときにクエリ キャッシュ有効化フラグが表示されず、その後はクエリ キャッシュが使用されなくなります。 たとえば、次のコードでは、クエリ キャッシュをリクエストしているにもかかわらず利用しません。

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

このコードを書き換えて、first ではなくnext を使用するようにすると、クエリ キャッシュが使用されます。

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

クエリは、キャッシュされた結果を生成した元のクエリと一致する場合、キャッシュされた結果を使用する資格があります。 2 つのクエリは、次の値が同一の場合、一致すると見なされます。

  • 名前空間(クエリが実行されたデータベースとコレクション)

  • セレクター(集計の場合、 集計パイプライン ステージ)

  • スキップ

  • Sort

  • プロジェクション

  • 照合

  • 読み取り保証(read concern)

  • 読み込み設定 (read preference)

たとえば、1 つのクエリを実行し、その後、異なるソート順序でほぼ同一のクエリを実行すると、それらのクエリは一致するとは見なされず、2 番目のクエリでは最初のクエリのキャッシュされた結果は使用されません。

制限を使用してクエリを実行する際、クエリ キャッシュは、より大きな制限を持つ既存のキャッシュされたクエリを再利用します(存在する場合)。 例:

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

クエリ キャッシュは、すべての書き込み操作で部分的にまたは完全にクリアされます。 ほとんどの書込み操作は、書込み先の同じコレクションに対して実行されたクエリの結果をクリアします。 一部の操作は、クエリ キャッシュ全体をクリアします。

次の操作により、同じデータベースとコレクション(一括書き込み中など)のキャッシュされたクエリ結果がクリアされます。

  • insert_one

  • update_one

  • replace_one

  • update_many

  • delete_one

  • delete_many

  • find_one_and_delete

  • find_one_and_update

  • find_one_and_replace

次の操作により、クエリ キャッシュ全体がクリアされます。

  • $mergeまたは$outパイプライン ステージでの集計

  • commit_transaction

  • abort_transaction

次の方法を使用して、いつでもクエリ キャッシュをクリアできます。

Mongo::QueryCache.clear

これにより、キャッシュされたクエリ結果がすべて削除されます。

クエリはトランザクションのコンテキスト内でキャッシュされますが、トランザクションがコミットまたは中止されると、キャッシュ全体がクリアされます。

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

注意

トランザクションは、多くの場合、「スナップショット」の読み取り保証レベルで実行されます。 「スナップショット」読み取り保証 (read concern) を持つクエリでは、「スナップショット」読み取り保証 (read concern) がないとクエリからキャッシュされた結果が返されないため、トランザクションが以前にキャッシュされたクエリを使用しない可能性があることに注意してください。

クエリがキャッシュされた結果をいつ使用するかを理解するには、「クエリの一致」セクションを参照してください。

クエリ キャッシュには、 集計パイプライン の結果もキャッシュされます。 例:

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

注意

集計結果は、例外なく、すべての書込み (write) 操作中にキャッシュからクリアされます。

MongoDB は、 database.system.*名前空間パターンを使用するコレクションにシステム情報を保存します。 これらは、システム コレクションと呼ばれます。

システム コレクション内のデータは、アプリケーションによってトリガーされないアクティビティ(内部サーバー プロセスなど)や、アプリケーションによって発行されたさまざまなデータベース コマンドの結果によって変更される可能性があります。 システム コレクションのキャッシュされた結果の期限が切れるタイミングを判断するのが困難であるため、システム コレクションのクエリはクエリ キャッシュをバイパスします。

システム コレクションの詳細については、 MongoDB ドキュメント を参照してください。

注意

クエリ キャッシュが有効になっている場合でも、システム コレクションからのクエリ結果はキャッシュされません。

ドライバーは、各ウェブリクエストの期間中にクエリ キャッシュを有効にする Rack ミドルウェアを提供します。 以下は、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

Rails on Rack ガイド を参照してください Rails アプリケーションで Rack ミドルウェアを使用する方法の詳細については、 を参照してください。

このドライバーは、各ジョブのクエリ キャッシュを有効にする Active Job ミドルウェアを提供します。 以下は、Ruby on Rails アプリケーションでクエリ キャッシュのアクティブ ジョブ ミドルウェアを有効にする方法の例です。

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

戻る

地理空間検索