Docs Menu
Docs Home
/ / /
Mongoid
/

永続性設定

項目一覧

  • ドキュメント ストレージ
  • 永続性コンテキスト属性
  • カスタム
  • モデルレベルの永続性オプション
  • ランタイム永続化オプション
  • クライアントとコレクションのアクセス

Mongoid はデフォルトで、クラス名の複数形であるコレクションにドキュメントを保存します。 次の Personクラスでは、ドキュメントが保存されるコレクションの名前はpeopleになります。

class Person
include Mongoid::Document
end

モデルクラス名の末尾には「s」を使用できません。これは、単語の複数形と見なされるためです。 たとえば、"Status" は "Statu" の複数形と見なされ、いくつかの既知の問題が発生します。

これは、Mongoid がファイル名とコレクション名からクラス名に変換するために使用するActiveSupport::Inflector#classifyの制限です。 モデル クラスにカスタムを指定することで、この問題を解決できます。 たとえば、次のコードはStatusという名前のモデルを処理します。

ActiveSupport::Inflector.inflections do |inflect|
inflect.singular("status", "status")
end

モデルのドキュメントのコレクションは、ドキュメントを別の場所で保持したい場合は、クラス レベルで変更できます。 また、モデルがデフォルトから永続化されるデータベースとクライアントを変更することもできます。

class Person
include Mongoid::Document
store_in collection: "citizens", database: "other", client: "analytics"
end

store_inマイクロは Lambda も受け入れることができます。この一般的なケースはマルチテナント アプリケーションです。

class Band
include Mongoid::Document
store_in database: ->{ Thread.current[:database] }
end

ドキュメントが データベースに保存されると、Ruby オブジェクトは BSON にシリアル化され、次のような構造になります。

{
"_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
"title" : "Sir",
"name" : {
"_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
"first_name" : "Durran"
},
"addresses" : [
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
"city" : "Berlin",
"country" : "Deutschland"
}
]
}

Mongoid は、永続性に使用されるクライアント、データベース、コレクション名を決定するために、モデル クラスにclient_namedatabase_namecollection_nameメソッドを提供します。

Band.client_name
# => :default
Band.database_name
# => "mongoid"
Band.collection_name
# => :bands

デフォルトとは異なるソース、またはデフォルトとは異なるオプションにドキュメントを永続化する場合がある場合があります。 Mongoid は、これのランタイム サポートとモデルごとのサポートを提供します。

モデルごとに、カスタム コレクション名、別のデータベース、または別のクライアントに保存するように指示できます。 次の例では、Band クラスは、クライアントが「analytics」を使用して、「Music」という名前のデータベース内の「artists」という名前のコレクションにデフォルトで保存されます。

clientオプションに指定される値は、mongoid.yml のclientsの下に構成する必要があることに注意してください。

class Band
include Mongoid::Document
store_in collection: "artists", database: "music", client: "analytics"
end

store_inマイクロが提供されていない場合、Mongoid はデフォルトのクライアントのデフォルトのデータベースにある「ands」という名前のコレクションにモデルを保存します。

モデル クラスまたは インスタンスでwithメソッドを使用して、操作のグループの永続性に使用されるクライアント、データベース、コレクション、および MongoDB クライアント オプションのいずれかを変更できます。

Band.with(database: "music-non-stop") do |klass|
klass.create(...)
band = Band.first
Band.create(...)
end
Band.with(collection: "artists") do |klass|
klass.delete_all
Band.delete_all
end
band.with(client: :tertiary) do |band_object|
band_object.save!
band.save!
end

withメソッドは、一時的な永続化コンテキストと、コンテキストでの操作に使用される MongoDB クライアントを作成します。 ブロック中、 withが呼び出されたモデル クラスまたはインスタンスの永続化コンテキストは、一時的な永続化コンテキストに変更されます。 便宜上、 withが呼び出されたモデル クラスまたはインスタンスは ブロックに降格します。

一時的な永続性コンテキストは、クエリと書込みの両方に適用されます。

異なる永続性コンテキストで永続性操作を実行する場合は注意が必要です。 たとえば、ドキュメントが一時的な永続性コンテキストに保存された場合、そのドキュメントはデフォルトの永続性コンテキストに存在せず、その後の更新は失敗します。

band = Band.new(name: "Scuba")
band.with(collection: "artists") do |band_object|
band_object.save!
end
# This will not save - updates the collection "bands" which does not have
# the Scuba band
band.update_attribute(likes: 1000)
# This will update the document.
band.with(collection: "artists") do |band_object|
band_object.update_attribute(likes: 1000)
end

Mongoid 6.0以降、 withメソッドは常にブロックとともに呼び出される必要があり、一時的な永続化コンテキストはブロックの期間のみ存在します。 これは、 withに渡されるオプションを使用して、 カバーの下に新しいクライアントが作成されるためです。 このクライアントを閉じ、関連するリソースを解放するには、このクライアントが使用できるスコープを明確に定義する必要があります。

実行時にすべての操作の永続性コンテキストを切り替えたいが、コード全体で を使用したくない場合、Mongoid はこれをクライアントとデータベース レベルでグローバルに実行する機能を提供します。 このメソッドはMongoid.override_clientMongoid.override_databaseです。 そのための有用なケースとして、異なるデータベースまたはクライアントに異なるロケールの情報を保存する国際化されたアプリケーションが挙げられますが、それぞれのスキーマは同じままです。

class BandsController < ApplicationController
before_action :switch_database
after_action :reset_database
private
def switch_database
I18n.locale = params[:locale] || I18n.default_locale
Mongoid.override_database("my_db_name_#{I18n.locale}")
end
def reset_database
Mongoid.override_database(nil)
end
end

上記の例では、すべての永続化操作が、このスレッド上の残りのすべての操作の代替データベースに保存されます。 これが、リクエスト後の でオーバーライドが nil に戻ります。これにより、ローカル パラメータのない後続のリクエストがデフォルト オプションを使用するようになります。

永続性コンテキストは、読み取り操作と書込み (write) 操作の両方に適用されます。 たとえば、セカンダリ読み取りは次のように実行できます。

Band.with(read: {mode: :secondary}) do
Band.count
end

ドライバー レベルにドロップダウンして操作を実行する場合は、モデルまたはドキュメント インスタンスからmongoクライアントまたは コレクションを取得できます。

Band.mongo_client
band.mongo_client
Band.collection
band.collection

ここから、クライアントの#withを使用した同じランタイム永続性オプションも利用できます。

client = Band.mongo_client.with(write: { w: 0 }, database: "musik")
client[:artists].find(...)

また、コレクション#withを使用して、 コレクションの :read オプションまたは 書込みオプションを上書きすることもできます。

collection_w_0 = Band.collection.with(write: { w: 0 })
collection_w_0[:artists].find(...)

戻る

map-reduce