結果を並べ替える
Overview
このガイドでは、ソート操作を使用して、MongoDB Java ドライバーによる読み取り操作の結果を並べ替える方法を学習します。
ソート操作では、クエリから返されたドキュメントを、指定されたソート条件で並べ替えます。 ソート基準は、データの順序付け方法を説明する MongoDB に渡すルールです。 ソート条件の例は、次のとおりです。
最小数から最大数へ
時刻までの時刻から最新時刻まで
名がアルファベット順に並べられている
次の場合は、こちらのガイドをお読みください。
昇順ソートと降順ソートを実行します。
ソート条件を組み合わせます。
このガイドの例では、次のドキュメントを含むサンプル コレクションを使用します。
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 6, "letter": "c", "food": "maple donut"}
ソートの方法
クエリによって検索した結果をソートすることも、集計パイプライン内の結果をソートすることもできます。 クエリ結果を並べ替えるには、 FindIterable
インスタンスの sort()
メソッドを使用します。 集計パイプライン内で結果を並べ替えるには、 Aggregates.sort()
静的ファクトリー メソッドを使用します。 これらのメソッドはどちらも、 Bson
インターフェースを引数として実装するオブジェクトを受け取ります。 詳細については、 BSON インターフェース用の API ドキュメントを参照してください。
次のように、 FindIterable
インスタンスのsort()
メソッドを使用できます。
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("_id"));
集計パイプライン内で次のようにAggregates.sort()
メソッドを使用できます。
import com.mongodb.client.model.Aggregates; import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.aggregate(Arrays.asList(Aggregates.sort(ascending("_id"))));
上記のコード スニペットは、サンプル コレクション内のドキュメントを_id
フィールドの最小値から最大値の順にソートします。
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} ...
上記のコード スニペットでは、 Sorts
ビルダ クラスを使用して並べ替え条件を指定しています。 Bson
インターフェースを実装する任意のクラスを使用して並べ替え条件を指定することも可能ですが、 Sorts
ビルダを使用して並べ替え条件を指定することをお勧めします。 Sorts
ビルダ クラスの詳細については、 Sort ビルダに関するガイドを参照してください。
このセクションのクラスとインターフェースの詳細については、次の API ドキュメントを参照してください。
ソート方向
並べ替えの方向は昇順または降順のいずれかです。 昇順で並べ替えると、結果が最小から最大の順に並べられます。 降順で並べ替えると、結果が最大から最小の順に並べられます。
以下に、昇順でソートされたデータの例をいくつか示します。
Numbers: 1, 2, 3, 43, 43, 55, 120
Dates: 1990-03-10, 1995-01-01, 2005-10-30, 2005-12-21
単語(ASCII) : バナー、ディル、によう
以下に、降順でソートされたデータの例をいくつか示します。
Numbers: 100, 30, 12, 12, 9, 3, 1
Dates: 2020-01-01, 1998-12-11, 1998-12-10, 1975-07-22
単語(逆 ASCII): ピアリング、品種、Apple、チームメイトのチーム
次のサブセクションでは、これらのソート条件を指定する方法を示します。
上昇
昇順の並べ替えを指定するには、 Sorts.ascending()
静的ファクトリー メソッドを使用します。 昇順で並べ替えるフィールドの名前をSorts.ascending()
メソッドに渡します。
次のように、 sort()
メソッドにSorts.ascending()
メソッドの出力を渡して、フィールドの昇順の並べ替えを指定できます。
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("<field name>"));
上記のsort()
メソッドでは、指定されたフィールド名で最小から最大の順にソートされて、コレクション内のドキュメントを反復処理できるFindIterable
オブジェクトが返されます。
次のコード例では、 ascending()
メソッドを使用してサンプル コレクションを_id
フィールドでソートします。
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> List<Document> results = new ArrayList<>(); collection.find().sort(ascending("_id")).into(results); for (Document result : results) { System.out.println(result.toJson()); }
上記のコードの出力は、次のようになります。
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} ...
下降
降順の並べ替えを指定するには、 Sorts.descending()
静的ファクトリー メソッドを使用します。 降順で並べ替えるフィールドの名前をSorts.descending()
メソッドに渡します。
次のコード スニペットは、 _id
フィールドで降順の並べ替えを指定する方法を示しています。
import static com.mongodb.client.model.Sorts.descending; // <MongoCollection setup code here> collection.find().sort(descending("_id"));
上記のコード スニペットは、サンプル コレクション内のドキュメントを降順で返します。
{"_id": 6, "letter": "c", "food": "maple donut"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} ...
同点の扱い
結果を並べ替えるために使用しているフィールドで 2 つ以上のドキュメントが同じ値を持つ場合、同順位となります。 MongoDB は、同点の場合のソート順序を保証しません。 たとえば、次のコードを使用してサンプル コレクションにソートを適用するときに、同点が発生したとします。
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("letter"));
クエリに一致したドキュメントには、ソートを実行するフィールドの値「a」が含まれているため、次のドキュメントは任意の順序で返されます。
{"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 2, "letter": "a", "food": "donuts and coffee"}
同じ値を持つフィールドを持つドキュメントの特定のソート順序を保証する必要がある場合は、同点の場合にソートするフィールドを追加して指定できます。
次のように、 letter
フィールドとそれに続く_id
フィールドで昇順の並べ替えを指定できます。
import static com.mongodb.client.model.Sorts.ascending; // <MongoCollection setup code here> collection.find().sort(ascending("letter", "_id"));
上記のコード スニペットは、サンプル コレクション内のドキュメントを次の順序で返します。
{"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 6, "letter": "c", "food": "maple donut"}
ソート条件の組み合わせ
並べ替え条件を結合するには、 Sorts.orderBy()
静的ファクトリー メソッドを使用します。 このメソッドは、ソート条件の順序付きリストを含むオブジェクトを構築します。 ソートを実行する際に、左端のソート条件が同値になった場合、ソートはリスト内の次のソート条件を使用して順序を決定します。
次のコード スニペットでは、 orderBy()
メソッドを使用して、 letter
フィールドで降順ソートを実行し、同点の場合は_id
フィールドで昇順ソートを実行してデータを順序付けます。
import static com.mongodb.client.model.Sorts.orderBy; import static com.mongodb.client.model.Sorts.ascending; import static com.mongodb.client.model.Sorts.descending; // <MongoCollection setup code here> Bson orderBySort = orderBy(descending("letter"), ascending("_id")); collection.find().sort(orderBySort);
上記のコード スニペットは、サンプル コレクション内のドキュメントを次の順序で返します。
{"_id": 1, "letter": "c", "food": "coffee with milk"} {"_id": 6, "letter": "c", "food": "maple donut"} {"_id": 4, "letter": "b", "food": "coffee with sugar"} {"_id": 2, "letter": "a", "food": "donuts and coffee"} {"_id": 3, "letter": "a", "food": "maple syrup"} {"_id": 5, "letter": "a", "food": "milk and cookies"}
テキスト検索
テキスト検索の結果の順序は、コレクションのテキストインデックスで指定された各結果のフィールドのstring値が検索stringとどの程度一致するかによって指定できます。 テキスト検索では、各結果が検索 string にどの程度一致するかを示す数値テキスト スコアが割り当てられます。 Sorts.metaTextScore()
静的ファクトリー メソッドを使用して、テキスト スコアで並べ替える並べ替え条件を構築します。
重要
テキストインデックスは必ず作成する
テキスト検索を実行するには、コレクションにテキストインデックスが必要です。 テキスト インデックスの作成方法の詳細については、サーバーのマニュアル ドキュメントを参照してください。
次のコード例では、 Sorts.metaTextScore()
メソッドを使用してサンプルコレクションのテキスト検索の結果を並べ替える方法を示しています。 このコード例では、フィルター、インデックス、およびプロジェクションビルダを使用します。 このコード例では、次のアクションが実行されます。
food
フィールドにサンプル コレクションのテキスト インデックスを作成します。 コレクションにすでに存在するインデックスを指定してcreateIndex()
を呼び出す場合、操作では新しいインデックスは作成されません。"maple double" というフレーズのテキスト検索を実行します。
クエリ結果にテキスト スコアを
score
フィールドとしてプロジェクションします。結果をテキスト スコアでソートします(一致が先)。
import com.mongodb.client.model.Sorts; import com.mongodb.client.model.Projections; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Indexes; // <MongoCollection setup code here> collection.createIndex(Indexes.text("food")); Bson metaTextScoreSort = Sorts.metaTextScore("score"); Bson metaTextScoreProj = Projections.metaTextScore("score"); String searchTerm = "maple donut"; Bson searchQuery = Filters.text(searchTerm); collection.find(searchQuery) .projection(metaTextScoreProj) .sort(metaTextScoreSort) .into(results); for (Document result : results) { System.out.println(result.toJson()); }
上記のコードの出力は、次のようになります。
{"_id": 6, "letter": "c", "food": "maple donut", "score": 1.5} {"_id": 2, "letter": "a", "food": "donuts and coffee", "score": 0.75} {"_id": 3, "letter": "a", "food": "maple syrup", "score": 0.75}
注意
MongoDB 4.4以降でのテキスト検索動作
MongoDB 4.4以降では、テキスト検索の構造が変更されました。 テキスト スコアで並べ替えるために、 Projections.metaTextScore()
をFindIterable
インスタンスにプロジェクションすることがなくなりました。 さらに、並べ替えで使用される$meta
テキスト スコア集計操作で指定したフィールド名は無視されます。 つまり、 Sorts.metaTextScore()
に渡したフィールド名引数は無視されます。
このセクションのクラスの詳細については、次の API ドキュメントを参照してください。
詳細については、「 ソート 」クラス を参照してください API ドキュメント。$textクエリ演算子と$meta集計パイプライン演算子の詳細については、サーバーのマニュアル ドキュメントを参照してください。