Docs Menu
Docs Home
/ / /
Kotlin コルーチン
/ / /

結果を並べ替える

このガイドでは、ソート操作を使用して、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(
@BsonId 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値が検索stringとどの程度一致するかによって指定できます。 テキスト検索では、各結果が検索 string にどの程度一致するかを示す数値テキスト スコアが割り当てられます。 Sorts.metaTextScore()静的ファクトリー メソッドを使用して、テキスト スコアで並べ替える並べ替え条件を構築します。

重要

テキストインデックスは必ず作成する

次のコード例では、 Sorts.metaTextScore()メソッドを使用してサンプルコレクションのテキスト検索の結果を並べ替える方法を示しています。 このコード例では、フィルターインデックス、およびプロジェクションビルダを使用します。

このコード例では、次のアクションが実行されます。

  1. descriptionフィールドにサンプル コレクションのテキスト インデックスを作成します。 コレクションにすでに存在するインデックスを指定してcreateIndex()を呼び出す場合、操作では新しいインデックスは作成されません。

  2. "vanilla"というフレーズのテキスト検索を実行します。

  3. クエリ結果にテキスト スコアをscoreフィールドとしてプロジェクションします。

  4. 結果をテキスト スコアでソートします(一致が先)。

データは、次の Kotlin データ クラスでモデル化されます。

data class OrderScore(
@BsonId 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集計パイプライン演算子の詳細については、サーバーのマニュアル ドキュメントを参照してください。

戻る

オープンChange Streams

項目一覧