Overview
このガイドでは、ソート操作を使用して、MongoDB Kotlin ドライバーで読み取り操作から結果を並べ替える方法を学習できます。
ソート操作では、クエリから返されたドキュメントを、指定されたソート条件で並べ替えます。 ソート基準は、データの順序付け方法を説明する MongoDB に渡すルールです。 ソート条件の例は、次のとおりです。
最小数から最大数へ
時刻までの時刻から最新時刻まで
名がアルファベット順に並べられている
次のアクションを実行する方法については、このガイドをお読みください。
昇順ソートと降順ソートの実行
ソート条件の組み合わせ
テキストクエリのテキスト スコアに基づいて並べ替え
このガイドの例では、次のドキュメントを含むサンプル コレクションを使用します。
{ "_id": 1, "date": "2022-01-03", "orderTotal": 17.86, "description": "1/2 lb cream cheese and 1 dozen bagels" }, { "_id": 2, "date": "2022-01-11", "orderTotal": 83.87, "description": "two medium vanilla birthday cakes" }, { "_id": 3, "date": "2022-01-11", "orderTotal": 19.49, "description": "1 dozen vanilla cupcakes" }, { "_id": 4, "date": "2022-01-15", "orderTotal": 43.62, "description": "2 chicken lunches and a diet coke" }, { "_id": 5, "date": "2022-01-23", "orderTotal": 60.31, "description": "one large vanilla and chocolate cake" }, { "_id": 6, "date": "2022-01-23", "orderTotal": 10.99, "description": "1 bagel, 1 orange juice, 1 muffin" }
このデータは、次の Kotlin データ クラスでモデル化されます。
data class Order( val id: Int, val date: String, val orderTotal: Double, val description: String, )
ソートの方法
クエリによって検索された結果をソートすることも、集計パイプライン内の結果をソートすることもできます。
クエリ結果を並べ替えるには、FindFlowインスタンスの sort() メソッドを使用します。集計パイプライン内で結果を並べ替えるには、Aggregates.sort() 静的ファクトリー メソッドを使用します。これらのメソッドはどちらも、Bson インターフェースを引数として実装するオブジェクトを受け取ります。詳細については、BSONインターフェースのAPIドキュメントを参照してください。
次のように、 FindFlowインスタンスのsort()メソッドを使用できます。
val resultsFlow = collection.find().sort(Sorts.ascending(Order::orderTotal.name))
集計パイプライン内でAggregates.sort()メソッドを使用して、サンプル コレクション内のドキュメントをorderTotalフィールドの最小値から最大値の順に並べ替えることができます。
val resultsFlow = collection.aggregate(listOf( Aggregates.sort(Sorts.ascending(Order::orderTotal.name)) )) resultsFlow.collect { println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin) Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels) Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes) Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke) Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake) Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)
上記のコード スニペットでは、 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()メソッドの出力を渡して、フィールドの昇順の並べ替えを指定できます。
collection.find().sort(Sorts.ascending("<field name>"))
上記のsort()メソッドでは、指定されたフィールド名で最小から最大の順にソートされて、コレクション内のドキュメントを反復処理できるFindIterableオブジェクトが返されます。
次のコード例では、 ascending()メソッドを使用してサンプル コレクションをorderTotalフィールドでソートします。
val resultsFlow = collection.find() .sort(Sorts.ascending(Order::orderTotal.name)) resultsFlow.collect { println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin) Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels) Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes) Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke) Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake) Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)
下降
降順の並べ替えを指定するには、 Sorts.descending()静的ファクトリー メソッドを使用します。 降順で並べ替える必要があるフィールドの名前をSorts.descending()メソッドに渡します。
次のコード スニペットは、 orderTotalフィールドで降順の並べ替えを指定し、サンプル コレクション内のドキュメントを降順で返す方法を示しています。
val resultsFlow = collection.find() .sort(Sorts.descending(Order::orderTotal.name)) resultsFlow.collect { println(it) }
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes) Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake) Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke) Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes) Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels) Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)
同点の扱い
結果を並べ替えるために使用しているフィールドで 2 つ以上のドキュメントが同じ値を持つ場合、同順位となります。 MongoDB は、同点の場合のソート順序を保証しません。 たとえば、次のコードを使用してサンプル コレクションにソートを適用するときに、同点が発生したとします。
collection.find().sort(Sorts.ascending(Order::date.name))
クエリに一致した複数のドキュメントのdateフィールドには同じ値が含まれているため、ドキュメントは一貫した順序で返されない可能性があります。
同じ値を持つフィールドを持つドキュメントの特定の順序を保証する必要がある場合は、同点の場合に並べ替えるフィールドを追加して指定できます。
dateフィールドとそれに続くorderTotalフィールドで昇順の並べ替えを指定すると、サンプル コレクション内のドキュメントが次の順序で返されます。
collection.find().sort(Sorts.ascending(Order::date.name, Order::orderTotal.name))
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels) Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes) Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes) Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke) Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin) Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)
ソート条件の組み合わせ
並べ替え条件を結合するには、 Sorts.orderBy()静的ファクトリー メソッドを使用します。 このメソッドは、ソート条件の順序付きリストを含むオブジェクトを構築します。 ソートを実行する際、前のソート条件が同値になった場合、ソートはリスト内の次のソート条件を使用して順序を決定します。
次のコード スニペットでは、 orderBy()メソッドを使用して、 dateフィールドで降順ソートを実行し、同点の場合はorderTotalフィールドで昇順ソートを実行してデータを順序付けます。 これらのソート条件を使用すると、コードはサンプル コレクション内のドキュメントを次の順序で返します。
val orderBySort = Sorts.orderBy( Sorts.descending(Order::date.name), Sorts.ascending(Order::orderTotal.name) ) val results = collection.find().sort(orderBySort) results.collect {println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin) Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake) Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke) Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes) Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes) Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)
テキストクエリ
テキスト クエリの結果の順序は、コレクションのテキストインデックスで指定された各結果のフィールドの string 値が検索文字列と一致する方法によって指定できます。テキストクエリは、各結果が検索文字列にどの程度一致するかを示す数値テキストスコアを割り当てます。Sorts.metaTextScore() 静的ファクトリー メソッドを使用して、テキスト スコアで並べ替える並べ替え条件を構築します。
重要
テキストインデックスは必ず作成する
テキストクエリを実行するには、コレクションにテキストインデックスが必要です。テキストインデックスの作成方法の詳細については、サーバーのマニュアルドキュメントを参照してください。
次のコード例では、 Sorts.metaTextScore()メソッドを使用してサンプルコレクションのテキスト検索の結果を並べ替える方法を示しています。 このコード例では、フィルター、インデックス、およびプロジェクションビルダを使用します。
このコード例では、次のアクションが実行されます。
descriptionフィールドにサンプル コレクションのテキスト インデックスを作成します。 コレクションにすでに存在するインデックスを指定してcreateIndex()を呼び出す場合、操作では新しいインデックスは作成されません。"vanilla"というフレーズのテキスト クエリを実行します。クエリ結果にテキスト スコアを
scoreフィールドとしてプロジェクションします。結果をテキスト スコアでソートします(一致が先)。
データは、次の Kotlin データ クラスでモデル化されます。
data class OrderScore( val id: Int, val description: String, val score: Double )
import com.mongodb.client.model.Sorts import com.mongodb.client.model.Projections import com.mongodb.client.model.Filters import com.mongodb.client.model.Indexes
collection.createIndex(Indexes.text(Order::description.name)) val metaTextScoreSort = Sorts.orderBy( Sorts.metaTextScore(OrderScore::score.name), Sorts.descending("_id") ) val metaTextScoreProj = Projections.metaTextScore(OrderScore::score.name) val searchTerm = "vanilla" val searchQuery = Filters.text(searchTerm) val results = collection.find<OrderScore>(searchQuery) .projection(metaTextScoreProj) .sort(metaTextScoreSort) results.collect { println(it) }
OrderScore(id=3, description=1 dozen vanilla cupcakes, score=0.625) OrderScore(id=5, description=one large vanilla and chocolate cake, score=0.6) OrderScore(id=2, description=two medium vanilla birthday cakes, score=0.6)
注意
MongoDB 4.4 以降でのテキストクエリの動作
MongoDB 4.4 以降でテキストクエリの構造が変更されました。テキスト スコアで並べ替えるには、Projections.metaTextScore() を FindFlowインスタンスにプロジェクト必要がなくなりました。さらに、並べ替えで使用される $meta テキスト スコア集計操作で指定したフィールド名は無視されます。つまり、Sorts.metaTextScore() に渡したフィールド名引数は無視されます。
このセクションのクラスの詳細については、次の API ドキュメントを参照してください。
詳細については、「 ソートクラスのAPIドキュメント 」を参照してください。$text クエリクエリ演算子と $meta 集計パイプライン演算子の詳細については、サーバーのマニュアル ドキュメントを参照してください。