クエリ キャッシュ
項目一覧
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 ミドルウェア
ドライバーは、各ウェブリクエストの期間中にクエリ キャッシュを有効にする 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