Overview
このガイドでは、MongoDB との照合を使用して、クエリまたは集計操作の結果を string 値で並べ替える方法を説明します。 照合は、特定の言語とロケールに適用される文字の順序付けとマッチング ルールのセットです。
照合の詳細については、このガイドの次のセクションを参照してください。
MongoDB の照合
MongoDB は、デフォルトで バイナリ照合 を使用して string をソートします。バイナリ照合では、ASCII 標準 の文字の値を使用して文字列を比較して順序付けます。特定の言語とロケールには、ASCII 文字値とは異なる特定の文字順序付け規則があります。
たとえば、カナダフランス語では、先行するすべての文字が同じ場合、右端のアクセント記号(発音区別符号)によって string の順序が決まります。 次のカナダフランス語の単語について考えてみます。
コピー
coté
côte
côté
バイナリ照合を使用する場合、MongoDB はそれらを次の順序でソートします。
cote coté côte côté
カナダ フランス語の照合を使用する場合、MongoDB は次に示すように異なる順序でそれらをソートします。
cote côte coté côté
照合の指定方法
MongoDB は、ほとんどのCRUD操作と集計で照合をサポートしています。サポートされている操作の完全なリストについては、照合をサポートする操作サーバーのマニュアル ページを参照してください。
ロケール コードとオプションのバリアントを次の string 形式で指定できます。
"<locale code>@collation=<variant code>"
次の例えでは、「de」ロケール コードと「 電話番号 」のバリアント コードを指定します。
"de@collation=phonebook"
バリアントを指定しない場合は、次のようにロケール コードの後をすべて省略します。
"de"
サポートされているロケールの完全なリストについては、サポートされている言語とロケール に関するサーバー マニュアルのページを参照してください。
次のセクションでは、MongoDB で照合を適用するさまざまな方法を説明します。
コレクション
コレクションを作成するときに、デフォルトの照合を設定できます。 指定された照合を使用してコレクションを作成すると、そのコレクションをスキャンするサポートされているすべての操作によって照合のルールが適用されます。
コレクションを作成するときにのみ、コレクションにデフォルトの照合を割り当てることができます。 ただし、既存のコレクションの新しいインデックスで照合を指定できます。 詳細については、このガイドの「インデックス」セクションを参照してください。
次のスニペットは、 itemsという新しいコレクションを作成するときに、「en_US」ロケール照合を指定する方法を示しています。
database.createCollection( "items", new CreateCollectionOptions().collation( Collation.builder().locale("en_US").build()));
照合が正常に作成されたかどうかを確認するには、次のように、そのコレクションのインデックスのリストを取得します。
MongoCollection<Document> collection = database.getCollection("items"); List<Document> indexes = new ArrayList<>(); collection.listIndexes().into(indexes); // Prints the collection's indexes and any default collations indexes.forEach(idx -> System.out.println(idx.toJson()));
コードの出力には、次の内容が含まれている必要があります。
{ ... "collation": { "locale": "en_US", ... } ... }
Index
コレクションに新しいインデックスを作成するときに、照合を指定できます。 インデックスには コレクション内のドキュメントの順序付けられた表現が保存されるため、 操作ではメモリ内で順序付けは実行されません。 インデックスを使用するには、操作が次の条件を満たす必要があります。
この操作では、インデックスで指定された照合と同じ照合を使用します。
操作は、照合を含むインデックスによってカバーされます。
次のコード スニペットは、昇順の「en_US」ロケール照合で「name」フィールドにインデックスを作成する方法を示しています。
MongoCollection<Document> collection = database.getCollection("items"); IndexOptions idxOptions = new IndexOptions(); // Defines options that set a collation locale idxOptions.collation(Collation.builder().locale("en_US").build()); // Creates an index on the "name" field with the collation and ascending sort order collection.createIndex(Indexes.ascending("name"), idxOptions);
照合が正常に作成されたかどうかを確認するには、次のように、そのコレクションのインデックスのリストを取得します。
MongoCollection<Document> collection = database.getCollection("items"); List<Document> indexes = new ArrayList<>(); collection.listIndexes().into(indexes); // Prints the collection's indexes and any default collations indexes.forEach(idx -> System.out.println(idx.toJson()));
上記のコードの出力には、次の内容が含まれている必要があります。
{ ... "collation": { "locale": "en_US", ... } ... }
次のコード スニペットは、同じ照合を指定し、前のコード スニペットで作成したインデックスによってカバーされる操作の例を示しています。
FindIterable<Document> cursor = collection.find() .collation(Collation.builder().locale("en_US").build()) .sort(Sorts.ascending("name"));
操作
サポートされている操作のいずれかに新しい照合をパラメータとして渡すことで、コレクションのデフォルトの照合を上書きできます。 ただし、この操作ではインデックスが使用されないため、インデックスによってカバーされる操作のパフォーマンスが低下する可能性があります。 インデックスで説明されていないソート操作の悪影響の詳細については、「クエリ結果をソートするためにインデックスを使用する 」に関するサーバーのマニュアル ページを参照してください。
次のコード スニペットは、次の特性を持つクエリ操作の例を示しています。
参照先のコレクションには、コレクションセクションで指定された照合と同様のデフォルトの照合 "en_US" が含まれています。
クエリでは、コレクションのデフォルトの照合インデックスでカバーされていないアイスランド語("is")照合を指定します。
指定された照合はインデックスでカバーされていないため、ソート操作はメモリ内で実行されます。
FindIterable<Document> cursor = collection.find() .collation(Collation.builder().locale("is").build()) .sort(Sorts.ascending("name"));
照合をサポートしないインデックスの種類
ほとんどの MongoDB インデックス タイプは照合をサポートしていますが、次のタイプはバイナリ比較のみをサポートしています。
Collation Options
このセクションでは、さまざまな照合オプションと、順序付けと一致の動作をさらに絞り込むための指定方法について説明します。
照合オプション | 説明 |
|---|---|
ロケール | Required. The ICU locale code for language and variant. locale() API Documentation |
バックワード | Whether to consider diacritics from the end of the string first. backwards() API Documentation |
大文字と小文字の区別 | Whether to consider case (upper or lower) as different values. caseLevel() API Documentation |
代替 | Whether to consider spaces and punctuation. collationAlternate() API Documentation |
caseFirst | Whether to consider uppercase or lowercase first. collationCaseFirst() API Documentation |
Max Vvariable | Whether to ignore whitespace or both whitespace and punctuation. This setting is only valid when the alternate setting is "shifted". collationMaxVariable() API Documentation |
強度 | ICU level of comparison. The default value is "tertiary". For more information about each level, see the ICU Comparison Levels. collationStrength() API Documentation |
正規化 | Whether to perform unicode normalization on the text as needed. For more information about unicode normalization, see Unicode Normalization Forms. normalization() API Documentation |
numericOrdering | Whether to order numbers according to numeric value rather than collation order. numericOrdering() API Documentation |
前述の照合オプションの値を指定するには、 Collation.Builderクラスを使用します。 次のコード スニペットに示すように、 build()メソッドを呼び出してCollationオブジェクトを構築できます。
Collation.builder() .caseLevel(true) .collationAlternate(CollationAlternate.SHIFTED) .collationCaseFirst(CollationCaseFirst.UPPER) .collationMaxVariable(CollationMaxVariable.SPACE) .collationStrength(CollationStrength.SECONDARY) .locale("en_US") .normalization(false) .numericOrdering(true) .build();
対応するメソッドとそれらが受け入れるパラメーターの詳細については、 Collection.Builder のAPIドキュメントを参照してください。
照合の例
このセクションには、照合をサポートする選択した MongoDB 操作の使用方法を示す例えが含まれています。 各例ごとに、次のドキュメントのコレクションから開始することを想定します。
{ "_id" : 1, "first_name" : "Klara" } { "_id" : 2, "first_name" : "Gunter" } { "_id" : 3, "first_name" : "Günter" } { "_id" : 4, "first_name" : "Jürgen" } { "_id" : 5, "first_name" : "Hannah" }
次の例では、"de@collation=nonbook" のロケールとバリアントの照合を指定しています。 照合の "de" 部分はジャーナル ロケールを指定し、"collation= 電話番号 " 部分はバリアントを指定します。 「de」ロケール照合には、最初の文字を大文字にすることで識別される固有名を優先するためのルールが含まれています。 "collation=devicebook" のバリアントでは、umelaut を持つ文字は、昇順のソートで、それらのない文字の前に並べ替えられます。
find() と sort() の例
次の例では、コレクションからソートされた結果を取得するときに照合を適用する方法を示しています。 この操作を実行するには、サンプルfind() collation()sort()コレクションで を呼び出し、 メソッドと メソッドをチェーンして、結果を受信する順序を指定します。
注意
次のコード例では、便宜上import com.mongodb.client.modelパッケージからのインポートを使用しています。
List<Document> results = new ArrayList<>(); // Retrieves all documents and applies a "de@collation-phonebook" collation and ascending sort to the results collection.find() .collation(Collation.builder().locale("de@collation=phonebook").build()) .sort(Sorts.ascending("first_name")).into(results); // Prints the JSON representation of the results if (results != null) { results.forEach(doc -> System.out.println(doc.toJson())); }
この操作をサンプル コレクションに対して実行すると、出力は次のようになります。
{"_id": 3, "first_name": "Günter"} {"_id": 2, "first_name": "Gunter"} {"_id": 5, "first_name": "Hannah"} {"_id": 4, "first_name": "Jürgen"} {"_id": 1, "first_name": "Klara"}
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
findOneAndUpdate() の例
このセクションでは、クエリの最初の一致をアップデートする操作で照合を指定する方法について説明します。 この操作の照合を指定するには、 FindOneAndUpdateOptionsオブジェクトをインスタンス化し、それに照合を設定して、それをfindOneAndUpdate()メソッドの呼び出しのパラメーターとして渡します。
この例では、次の内容を示します。
昇順で「Gunter」に先行するサンプル コレクション内の最初のドキュメントを取得します。
"de@collation=non-book" 照合を含む操作のオプションを設定します。
値が「true」である「検証済み」の新しいフィールドを追加します。
更新されたドキュメントを取得して印刷します。
注意
次のコード例では、便宜上import com.mongodb.client.modelパッケージからのインポートを使用しています。
Document result = collection.findOneAndUpdate( Filters.gt("first_name", "Gunter"), Updates.set("verified", true), new FindOneAndUpdateOptions() .collation(Collation.builder().locale("de@collation=phonebook").build()) .sort(Sorts.ascending("first_name")) .returnDocument(ReturnDocument.AFTER)); // Prints the JSON representation of the updated document if an update occurred if (result != null) { System.out.println("Updated document: " + result.toJson()); }
"Guter" は、昇順のde@collation=phonebook照合を使用して、辞書的に "Gunter" より前にあるため、上記の操作は次の更新ドキュメントを返します。
{ lastErrorObject: { updatedExisting: true, n: 1 }, value: { _id: 3, first_name: 'Günter' }, ok: 1 }
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
findOneAndDelete() の例
このセクションでは、クエリから最初の一致を削除する操作の照合で、string の番号順を指定する方法を示します。 この操作の照合を指定するには、 FindOneAndDeleteOptionsオブジェクトをインスタンス化し、それに数値順序照合を設定して、それをfindOneAndDelete()メソッドの呼び出しのパラメーターとして渡します。
この例では、次のドキュメントを含むコレクションに対してfindOneAndDelete()操作を呼び出します。
{ "_id" : 1, "a" : "16 apples" } { "_id" : 2, "a" : "84 oranges" } { "_id" : 3, "a" : "179 bananas" }
照合では、番号順に基づいて文字列を並べ替えるために、 localeオプションを "en" に設定し、 numericOrderingオプションを "true" に設定します。
注意
次のコード例では、便宜上import com.mongodb.client.modelパッケージからのインポートを使用しています。
Document result = collection.findOneAndDelete( Filters.gt("a", "100"), new FindOneAndDeleteOptions() .collation( Collation.builder() .locale("en") .numericOrdering(true) .build()) .sort(Sorts.ascending("a"))); // Prints the JSON representation of the deleted document if (result != null) { System.out.println("Deleted document: " + result.toJson()); }
上記の操作を実行すると、出力は次のようになります。
Deleted document: {"_id": 3, "a": "179 bananas"}
string "179" の数値は数値 100 より大きいため、前のドキュメントが唯一の一致となります。
3 つのドキュメントの元のコレクションに対して数値順序照合を実行せずに同じ操作を実行すると、バイナリ照合で順序付けている場合、"100" が "16"、"84"、"179" の前に配置されるため、フィルターはすべてのドキュメントと一致します。
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
集計の例
このセクションでは、集計操作で照合を指定する方法を説明します。 集計操作では、一連の集計ステージを指定できます。これは合計で集計パイプラインと呼ばれます。 集計を実行するには、 MongoCollectionオブジェクトでaggregate()メソッドを呼び出します。
集計操作の照合を指定するには、集計操作によって返されたAggregateIterableでcollation()メソッドを呼び出します。 集計パイプラインで照合を適用する並べ替え集計ステージを必ず指定してください。
次の例は、サンプルコレクションに集計パイプラインを構築し、以下を指定して照合を適用する方法を示しています。
Aggregates.group()ヘルパーを使用してfirst_nameフィールドで各ドキュメントを識別し、その値を結果の_idとして使用するグループ集計ステージ。first_nameフィールドに一致する値のインスタンス数を合計するための グループ集計ステージ のアキュムレータ。前の集計ステージの出力ドキュメントの
_idフィールドに昇順 並べ替え を適用します。ドイツ語のロケールと、アクセントや記号を無視する照合強度を指定して、照合オブジェクトを構築します。
Bson groupStage = Aggregates.group("$first_name", Accumulators.sum("nameCount", 1)); Bson sortStage = Aggregates.sort(Sorts.ascending("_id")); AggregateIterable<Document> results = collection // Runs the aggregation pipeline that includes tallying "first_name" frequencies .aggregate(Arrays.asList(groupStage, sortStage)) // Applies a collation to sort documents alphabetically by using the German locale, ignoring accents .collation(Collation.builder().locale("de").collationStrength(CollationStrength.PRIMARY).build()); // Prints the JSON representation of the results if (results != null) { results.forEach(doc -> System.out.println(doc.toJson())); }
上記のコードでは、次のドキュメントが出力されます。
{"_id": "Gunter", "nameCount": 2} {"_id": "Hannah", "nameCount": 1} {"_id": "Jürgen", "nameCount": 1} {"_id": "Klara", "nameCount": 1}
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。