照合
Overview
バージョン 3.4 で追加。
照合は、string を比較する方法に関するルールのセットです。通常、特定の自然言語で行われます。
たとえば、カナダフランス語では、特定の単語の最後のアクセントによって並べ替え順序が決まります。
次のフランス語の単語を考えてみましょう。
cote < coté < côte < côté
カナダ フランス語の照合を使用したソート順では、次のようになります。
cote < côte < coté < côté
照合が指定されていない場合、MongoDB は string に対して単純なバイナリ比較を使用します。 そのため、単語のソート順序は次のようになります。
cote < coté < côte < côté
使用法
作成時にコレクションとインデックスのデフォルトの照合を指定することも、CRUD 操作や集計の照合を指定することもできます。 照合をサポートする操作の場合、操作で別の照合順序が指定されていない限り、MongoDB ではコレクションのデフォルトの照合順序が使用されます。
照合パラメータ
'collation' => { 'locale' => <string>, 'caseLevel' => <bool>, 'caseFirst' => <string>, 'strength' => <int>, 'numericOrdering' => <bool>, 'alternate' => <string>, 'maxVariable' => <string>, 'normalization' => <bool>, 'backwards' => <bool> }
必要なパラメータはlocale
のみです。サーバーはこれを ICU 形式のロケール ID として解析します。 。たとえば、米国英語を表す場合はlocale
をen_US
に設定し、カナダフランス語を表す場合はfr_CA
を設定します。
利用可能なパラメータの完全な説明については、 MongoDB マニュアル エントリを参照してください。
コレクションへのデフォルトの照合の割り当て
次の例では、 test
データベースにcontacts
という新しいコレクションを作成し、 fr_CA
ロケールのデフォルトの照合を割り当てます。 コレクションの作成時に照合を指定すると、クエリで別の照合が指定されていない限り、 contacts
コレクションに対して実行されるクエリに関係するすべての操作でfr_CA
照合が使用されるようになります。 また、作成コマンドで別の照合順序が指定されていない限り、新しいコレクションのすべてのインデックスもデフォルトの照合順序を継承します。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") client[:contacts, { "collation" => { "locale" => "fr_CA" } } ].create
インデックスへの照合の割り当て
インデックスの照合を指定するには、インデックスを作成するときにcollation
オプションを使用します。
次の例では、 address_book
コレクションのname
フィールドにインデックスを作成し、 unique
パラメータを有効にし、 locale
をen_US
に設定したデフォルトの照合 を使用します。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") client[:address_book].indexes.create_one( { "first_name" => 1 }, "unique" => true, "collation" => { "locale" => "en_US" } )
このインデックスを使用するには、クエリでも同じ照合を指定していることを確認してください。 次のクエリでは、上記のインデックスを使用します。
client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US" })
次のクエリでは、インデックスは使用されません。 最初のクエリでは照合は使用されず、2 番目のクエリではインデックスの照合とは異なるstrength
値を持つ照合が使用されます。
client[:address_book].find({"first_name" : "Adam" }) client[:address_book].find({"first_name" : "Adam" }, "collation" => { "locale" => "en_US", "strength" => 2 })
照合をサポートする操作
すべての読み取り、更新、削除メソッドは照合をサポートしています。 いくつかの例を以下に示します。
find()
および sort()
結果をマッチングおよびソートするときに使用する照合を、個々のクエリで指定できます。 次のクエリとソート操作では、 locale
パラメータがde
に設定されているジャーナル照合を使用します。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") docs = client[:contacts].find({ "city" => "New York" }, { "collation" => { "locale" => "de" } }).sort( "name" => 1 )
find_one_and_update()
names
というコレクションには次のドキュメントが含まれています。
{ "_id" : 1, "first_name" : "Hans" } { "_id" : 2, "first_name" : "Gunter" } { "_id" : 3, "first_name" : "Günter" } { "_id" : 4, "first_name" : "Jürgen" }
コレクションに対する次のfind_one_and_update
操作では、照合を指定していません。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") doc = client[:names].find_one_and_update( {"first_name" => { "$lt" => "Gunter" }}, { "$set" => { "verified" => true } })
Gunter
は辞書的にコレクションの最初であるため、上記の操作では結果は返されず、ドキュメントは更新されません。
同じfind_one_and_update
操作を実行しますが、照合は が指定されている場合を考えてみましょう。 ロケールはde@collation=phonebook
に設定されています。
注意
一部のロケールでは、固有名を他の単語とは異なる方法でソートする言語で使用できるcollation=phonebook
オプションがあります。 de@collation=phonebook
照合によると、ulimit を持つ文字は、numlaut のない同じ文字の前にあります。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") doc = client[:names].find_one_and_update( { "first_name" => { "$lt" => "Gunter" } }, { "$set" => { "verified" => true } }, { "collation" => { "locale" => "de@collation=phonebook" }, :return_document => :after } )
この操作により、次の更新されたドキュメントが返されます。
{ "_id" => 3, "first_name" => "Günter", "verified" => true }
find_one_and_delete()
numericOrdering
照合パラメータをtrue
に設定して、数値 string を数値で比較します。
コレクションnumbers
には次のドキュメントが含まれています。
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
次の例では、フィールドa
の数値が 100 より大きい最初のドキュメントを照合し、そのドキュメントを削除します。
docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } }, { "collation" => { "locale" => "en", "numericOrdering" => true } })
上記の操作後、次のドキュメントが コレクションに残ります。
{ "_id" : 1, "a" : "16" } { "_id" : 2, "a" : "84" }
照合なしで同じ操作を実行すると、サーバーはa
の句読点が"100"
より大きい最初に見つけたドキュメントを削除します。
numbers = client[:numbers] docs = numbers.find_one_and_delete({ "a" => { "$gt" => "100" } })
上記の操作後、 a
が"16"
に等しいドキュメントは削除され、次のドキュメントが コレクションに残ります。
{ "_id" : 2, "a" : "84" } { "_id" : 3, "a" : "179" }
delete_many()
Ruby ドライバーに存在するさまざまな一括操作で照合を使用できます。
コレクションrecipes
には次のドキュメントが含まれています。
{ "_id" : 1, "dish" : "veggie empanadas", "cuisine" : "Spanish" } { "_id" : 2, "dish" : "beef bourgignon", "cuisine" : "French" } { "_id" : 3, "dish" : "chicken molé", "cuisine" : "Mexican" } { "_id" : 4, "dish" : "chicken paillard", "cuisine" : "french" } { "_id" : 5, "dish" : "pozole verde", "cuisine" : "Mexican" }
照合ドキュメントのstrength
パラメータを1
または2
に設定すると、サーバーはクエリフィルターで大文字と小文字を無視します。 次の例では、大文字と小文字を区別しないクエリフィルターを使用して、 cuisine
フィールドがFrench
と一致するすべてのレコードを削除します。
client = Mongo::Client.new([ "127.0.0.1:27017" ], :database => "test") recipes = client[:recipes] docs = recipes.delete_many({ "cuisine" => "French" }, "collation" => { "locale" => "en_US", "strength" => 1 })
上記の操作が実行されると、 _id
値が2
と4
であるドキュメントがコレクションから削除されます。
集計
集計操作で照合を使用するには、集計オプションで照合を指定します。
次の集計例では、 names
というコレクションを使用してfirst_name
フィールドをグループ化し、各グループの結果の合計数をカウントし、結果をジャーナル電話番号でソートします。
aggregation = names.aggregate( [ { "$group" => { "_id" => "$first_name", "name_count" => { "$sum" => 1 } } }, { "$sort" => { "_id" => 1 } }, ], { "collation" => { "locale" => "de@collation=phonebook" } } ) aggregation.each do |doc| #=> Yields a BSON::Document. end