結果のページ分割
項目一覧
MongoDB 6.0.13 + または7.0.5 + を実行している Atlas クラスターでは、 Atlas Search を使用して、 $search
クエリ結果を参照点の後、または前に順番に取得します。 $search
searchAfter
またはsearchBefore
オプションを使用して結果を順番に走査し、アプリケーション内に「次のページ」と「前のページ」関数を構築します。
使用法
ページ分割された結果を検索するには、次の手順を実行します。
クエリを実行したいフィールドにインデックスを作成します。
参照点を返す
$search
クエリを実行します。 詳しくは、「 参照点を取得する 」を参照してください。後続の
$search
クエリで参照点を使用して、結果内に次または前のドキュメント セットを検索します。"Next Page" 関数を構築するための結果の検索の詳細については、「特定の参照点の後の検索 」を参照してください。
「前のページ」関数を構築するための結果の検索の詳細については、「特定の参照点の前の検索 」を参照してください。
結果のページに移動するには、
$skip
と$limit
を$search
searchAfter
またはsearchBefore
オプションと組み合わせて使用します。 たとえば、ページ3からページ5に移動し、1 ページあたり10の結果に移動するには、次の操作を実行します。ページ3の最後の結果の参照点を持つ
searchAfter
を使用して結果を取得します(結果30 )。ページ4の10結果(結果31 - 40 )をスキップするには
$skip
を使用し、結果を10ドキュメントに制限するには、$limit
を使用します。ページ5の結果を返します(結果41 - 50 )。
ここで、
searchAfter
オプションとともに$skip
を使用すると、クエリが最適化され、結果の1ページのみをスキップできます( 10ドキュメント)。 一方、$search
searchAfter
オプションなしで$skip
を使用すると、クエリは4ページの結果( 40ドキュメント)をスキップします。 詳しくは、「searchAfter
と$skip
を使用してページ2からページ5に移動する 」を参照してください。
Considerations
複数のドキュメントが同じ値を持つフィールドでソートすると、同順位となります。 MongoDBでは、関連付けられたクエリ結果の順序が保証されていないため、 searchAfter
と searchBefore
を使用すると重複や不整合が発生する可能性があります。決定的な検索動作を確保するには、次の原則を適用します。
関連性スコアが同値になるのを防ぐために、クエリを一意のフィールドでソートします。
非 一意のフィールドで主にソートする場合は、タイブレークとして機能するために一意のフィールドに セカンダリ ソート句を追加 します。
クエリ結果を不変フィールドでソートします。 Atlas Search は、最初のクエリと後続のクエリの間にコレクションに加えた更新を反映します。
updated_time
などの可変フィールドでソートし、最初と 2 番目のクエリの間にコレクションを更新すると、Atlas Search は同じドキュメントの順序付け方法が異なる場合があります。
不変または一意のフィールドでクエリ結果を並べ替える方法については、「 Atlas Search結果の並べ替え 」を参照してください。
参照点の取得
特定の時点でクエリ結果を検索するには、 $search
クエリで参照点を指定する必要があります。 参照点を検索するには、 ステージの後の$meta
searchSequenceToken
$project
ステージで$search
キーワード を使用します。
構文
1 [{ 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 } 7 "sort": { 8 "score": { 9 "$meta": "searchScore", _id:1 10 } 11 } 12 ... 13 }, 14 { 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }]
出力
searchSequenceToken
は、結果内の各ドキュメントに対して base 64でエンコードされたトークンを生成します。 トークンの長さは、クエリのソートオプションで指定されたフィールドの数に応じて増加します。 トークンはデータベースのスナップショットには関連付けられていません。
クエリでsort
オプションを指定しない限り、結果内のドキュメントはデフォルトの順序でソートされます。 結果の並べ替えの詳細については、「 Atlas Search結果の並べ替え 」を参照してください。
特定の参照点の後の検索
参照点を検索するには、 searchSequenceToken
によって生成されたトークンでsearchAfter
オプションを使用して、 $search
クエリで参照点を指定する必要があります。 searchSequenceToken
によって生成されたトークンは、 searchSequenceToken
がトークンを生成した$search
クエリを再実行した場合にのみ使用できます。 トークンを使用する後続の$search
クエリのセマンティクス(検索フィールドと値)は、 searchSequenceToken
がトークンを生成したクエリと同一である必要があります。
searchAfter
オプションを使用して、アプリケーション内で「次のページ」機能を構築できます。 これを示すには、このページの例を参照してください。
searchAfter
構文
1 { 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 }, 7 "searchAfter": "<base64-encoded-token>", 8 "sort": { 9 "score": { 10 "$meta": "searchScore", _id:1 11 } 12 } 13 ... 14 }, 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }
出力
Atlas Search では、指定トークンの発行後に結果内のドキュメントが返されます。 Atlas Search では、 $search
ステージの後の$project
ステージでsearchSequenceToken
を指定したため、結果内のドキュメントの生成されたトークンが返されます( 11行に表示)。 これらのトークンは、同じセマンティクスを持つ別のクエリの参照ポイントとして使用できます。
クエリでsort
オプションを指定しない限り、結果内のドキュメントはデフォルトの順序でソートされます。 結果の並べ替えの詳細については、「 Atlas Search結果の並べ替え 」を参照してください。
特定の参照点の前の検索
参照点の前を検索するには、 searchSequenceToken
によって生成されたトークンでsearchBefore
オプションを使用して、 $search
クエリで参照点を指定する必要があります。 searchSequenceToken
によって生成されたトークンは、 searchSequenceToken
がトークンを生成した$search
クエリを再実行した場合にのみ使用できます。 トークンを使用する後続の$search
クエリのセマンティクス(検索フィールドと値)は、 searchSequenceToken
がトークンを生成したクエリと同一である必要があります。
searchBefore
オプションを使用して、アプリケーション内で「前のページ」機能を構築できます。 「前のページ」機能を構築するには、以下を組み合わせます。
これを証明するために、このページのsearchBefore
クエリ例を参照してください。
searchBefore
構文
1 { 2 "$search": { 3 "index": "<index-name>", 4 "<operator-name>"|"<collector-name>": { 5 <operator-specification>|<collector-specification> 6 }, 7 "searchBefore": "<base64-encoded-token>", 8 "sort": { 9 "score": { 10 "$meta": "searchScore", _id:1 11 } 12 } 13 ... 14 }, 15 "$project": { 16 { "paginationToken" : { "$meta" : "searchSequenceToken" } } 17 }, 18 ... 19 }
searchBefore
出力
Atlas Search では、指定されたトークンに先行する結果内のドキュメントが逆の順序で返されます。 Atlas Search では、searchSequenceToken
$project
$search
ステージの後の ステージで を指定したため、結果内のドキュメントの生成されたトークンも返されます(11 行に表示されているように)。これらのトークンは、同じセマンティクスを持つ別のクエリの参照ポイントとして使用できます。
例
次の例えでは、動的マッピングを持つdefault
という名前の Atlas Search インデックスがあるsample-mflix.moviesコレクションを使用します。 コレクションをロードしてインデックスを作成すると、コレクションに対して次のクエリを実行できます。
searchSequenceToken
クエリ
次のクエリでは、次のパイプライン ステージを使用します。
$search
必要に応じて、次の操作を実行します。コレクションの
title
フィールドでwar
というタームを検索します。最初にスコアで結果を並べ替え、次に
released
フィールドの値で並べ替え、スコアが同一のドキュメントの昇順で結果を並べ替えます。
$limit
ステージを使用して、結果を10
ドキュメントに制限します。$project
ステージでは、次を実行できます。title
released
フィールドと フィールドのみを含めます。次のフィールドを追加します。
各ドキュメントの base64 でエンコードされたトークンを含む
paginationToken
という名前のフィールド。各ドキュメントの関連性スコアを含む
score
という名前のフィールド。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1} 9 } 10 }, 11 { 12 "$limit": 10 13 }, 14 { 15 "$project": { 16 "_id": 0, 17 "title": 1, 18 "released": 1, 19 "paginationToken" : { "$meta" : "searchSequenceToken" }, 20 "score": {$meta: "searchScore"} 21 } 22 } 23 ])
1 [ 2 { 3 title: 'War', 4 released: ISODate('2002-03-14T00:00:00.000Z'), 5 paginationToken: 'CMFRGgYQup3BhQgaCSkAQCKS7AAAAA==', 6 score: 3.3774025440216064 7 }, 8 { 9 title: 'War', 10 released: ISODate('2014-09-21T00:00:00.000Z'), 11 paginationToken: 'CMelARoGELqdwYUIGgkpAAiClUgBAAA=', 12 score: 3.3774025440216064 13 }, 14 { 15 title: 'War Photographer', 16 paginationToken: 'CMBRGgYQuq+ngwgaAmAA', 17 score: 2.8268959522247314 18 }, 19 { 20 title: "Troma's War", 21 released: ISODate('1989-11-18T00:00:00.000Z'), 22 paginationToken: 'CL8kGgYQuq+ngwgaCSkAbP8QkgAAAA==', 23 score: 2.8268959522247314 24 }, 25 { 26 title: 'The War', 27 released: ISODate('1994-11-04T00:00:00.000Z'), 28 paginationToken: 'CI0wGgYQuq+ngwgaCSkAnIKEtgAAAA==', 29 score: 2.8268959522247314 30 }, 31 { 32 title: 'War Stories', 33 released: ISODate('1996-05-09T00:00:00.000Z'), 34 paginationToken: 'CPIyGgYQuq+ngwgaCSkA/DifwQAAAA==', 35 score: 2.8268959522247314 36 }, 37 { 38 title: "Gaston's War", 39 released: ISODate('1997-10-23T00:00:00.000Z'), 40 paginationToken: 'CMQ7GgYQuq+ngwgaCSkALPBSzAAAAA==', 41 score: 2.8268959522247314 42 }, 43 { 44 title: 'Shooting War', 45 released: ISODate('2000-12-07T00:00:00.000Z'), 46 paginationToken: 'CMJJGgYQuq+ngwgaCSkAOOhG4wAAAA==', 47 score: 2.8268959522247314 48 }, 49 { 50 title: "Varian's War", 51 released: ISODate('2001-04-22T00:00:00.000Z'), 52 paginationToken: 'CM5IGgYQuq+ngwgaCSkAGEkD5gAAAA==', 53 score: 2.8268959522247314 54 }, 55 { 56 title: "Hart's War", 57 released: ISODate('2002-02-15T00:00:00.000Z'), 58 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 59 score: 2.8268959522247314 60 } 61 ]
注意
結果内のドキュメントのトークンが異なる場合があります。 searchAfter
クエリまたは searchBefore
クエリを実行する前に、後続のクエリのトークンを、 Atlas Searchが結果に返したトークンに置き換えます。
後続の searchAfter
および searchBefore
クエリ
次のクエリでは、同じセマンティクスを持つ別のクエリのトークンを使用して、指定されたトークンの前後でページ分割された結果を検索します。 例のsearchSequenceToken
クエリを実行した場合、結果に含まれるドキュメントのトークンが異なる場合があります。 このセクションのクエリ内のトークンを、クエリ結果で返されたトークンに置き換えてください。
クエリは、次のパイプライン ステージを使用します。
$search
ステージでは、次を実行できます。Atlas Search の結果から、
title
フィールドでwar
というタームを見つけるドキュメントを検索します。最初にスコアで結果を並べ替え、次に
released
フィールドの値で並べ替え、スコアが同一のドキュメントの昇順で結果を並べ替えます。
$limit
ステージを使用して、結果を10
ドキュメントに制限します。$project
ステージでは、次を実行できます。title
released
ドキュメントには フィールドと フィールドのみを含めます。次のフィールドを追加します。
各ドキュメントの base64 でエンコードされたトークンを含む
paginationToken
という名前のフィールド。各ドキュメントの関連性スコアを含む
score
という名前のフィールド。
参照点の後の検索
次のクエリは、指定された参照ポイントの後のtitle
フィールドにwar
というタームを含む Atlas Search 結果内のドキュメントをリクエストします。 searchSequenceToken
クエリ結果の最後のドキュメントに関連付けられたトークン( 58行)を参照ポイントとして、結果内の次の10
ドキュメントを検索します。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchAfter": "CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ])
1 [ 2 { 3 title: 'The War', 4 released: ISODate('2007-09-23T00:00:00.000Z'), 5 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'War, Inc.', 10 released: ISODate('2008-06-13T00:00:00.000Z'), 11 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'War, Inc.', 16 released: ISODate('2008-06-13T00:00:00.000Z'), 17 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'War Dance', 22 released: ISODate('2008-11-01T00:00:00.000Z'), 23 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Horse', 28 released: ISODate('2011-12-25T00:00:00.000Z'), 29 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'Cold War', 34 released: ISODate('2012-11-08T00:00:00.000Z'), 35 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'Drug War', 40 released: ISODate('2013-04-04T00:00:00.000Z'), 41 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'War Story', 46 released: ISODate('2014-07-30T00:00:00.000Z'), 47 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'A War', 52 released: ISODate('2015-09-10T00:00:00.000Z'), 53 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 54 score: 2.8268959522247314 55 }, 56 { 57 title: 'War Pigs', 58 released: ISODate('2015-09-18T00:00:00.000Z'), 59 paginationToken: 'CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=', 60 score: 2.8268959522247314 61 } 62 ]
参照点の前の検索
次のクエリは、指定された参照点の前のtitle
フィールドにあるタームwar
の Atlas Search 結果をリクエストします。 サンプルsearchAfter
クエリ結果内の最後のドキュメントに関連付けられたトークン( 59行)を参照ポイントとして、先行する10
ドキュメントを結果から検索します。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchBefore": "CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ])
1 [ 2 { 3 title: 'A War', 4 released: ISODate('2015-09-10T00:00:00.000Z'), 5 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'War Story', 10 released: ISODate('2014-07-30T00:00:00.000Z'), 11 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'Drug War', 16 released: ISODate('2013-04-04T00:00:00.000Z'), 17 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'Cold War', 22 released: ISODate('2012-11-08T00:00:00.000Z'), 23 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Horse', 28 released: ISODate('2011-12-25T00:00:00.000Z'), 29 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'War Dance', 34 released: ISODate('2008-11-01T00:00:00.000Z'), 35 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'War, Inc.', 40 released: ISODate('2008-06-13T00:00:00.000Z'), 41 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'War, Inc.', 46 released: ISODate('2008-06-13T00:00:00.000Z'), 47 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'The War', 52 released: ISODate('2007-09-23T00:00:00.000Z'), 53 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 54 score: 2.8268959522247314 55 }, 56 { 57 title: "Hart's War", 58 released: ISODate('2002-02-15T00:00:00.000Z'), 59 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 60 score: 2.8268959522247314 61 } 62 ]
上記のクエリでは、Atlas Search 結果が逆の順序であることがわかります。 次のクエリでは、 $limit
ステージをtoArray()メソッドとreverse()
メソッドとともに使用して、「前のページ」のような関数を構築します。
1 db.movies.aggregate([ 2 { 3 "$search": { 4 "text": { 5 "path": "title", 6 "query": "war" 7 }, 8 "sort": {score: {$meta: "searchScore"}, "released": 1}, 9 "searchBefore": "CJ6kARoGELqvp4MIGgkpACDA3U8BAAA=" 10 } 11 }, 12 { 13 "$limit": 10 14 }, 15 { 16 "$project": { 17 "_id": 0, 18 "title": 1, 19 "released": 1, 20 "paginationToken" : { "$meta" : "searchSequenceToken" }, 21 "score": { "$meta": "searchScore" } 22 } 23 } 24 ]).toArray().reverse()
1 [ 2 { 3 title: "Hart's War", 4 released: ISODate('2002-02-15T00:00:00.000Z'), 5 paginationToken: 'CMtJGgYQuq+ngwgaCSkAjBYH7AAAAA==', 6 score: 2.8268959522247314 7 }, 8 { 9 title: 'The War', 10 released: ISODate('2007-09-23T00:00:00.000Z'), 11 paginationToken: 'CP9xGgYQuq+ngwgaCSkA1KkvFQEAAA==', 12 score: 2.8268959522247314 13 }, 14 { 15 title: 'War, Inc.', 16 released: ISODate('2008-06-13T00:00:00.000Z'), 17 paginationToken: 'COhuGgYQuq+ngwgaCSkAtDh/GgEAAA==', 18 score: 2.8268959522247314 19 }, 20 { 21 title: 'War, Inc.', 22 released: ISODate('2008-06-13T00:00:00.000Z'), 23 paginationToken: 'COluGgYQuq+ngwgaCSkAtDh/GgEAAA==', 24 score: 2.8268959522247314 25 }, 26 { 27 title: 'War Dance', 28 released: ISODate('2008-11-01T00:00:00.000Z'), 29 paginationToken: 'CONvGgYQuq+ngwgaCSkAYFlVHQEAAA==', 30 score: 2.8268959522247314 31 }, 32 { 33 title: 'War Horse', 34 released: ISODate('2011-12-25T00:00:00.000Z'), 35 paginationToken: 'CJWFARoGELqvp4MIGgkpAEyEcjQBAAA=', 36 score: 2.8268959522247314 37 }, 38 { 39 title: 'Cold War', 40 released: ISODate('2012-11-08T00:00:00.000Z'), 41 paginationToken: 'CJGUARoGELqvp4MIGgkpAPBQ3ToBAAA=', 42 score: 2.8268959522247314 43 }, 44 { 45 title: 'Drug War', 46 released: ISODate('2013-04-04T00:00:00.000Z'), 47 paginationToken: 'CMWTARoGELqvp4MIGgkpAMRX0j0BAAA=', 48 score: 2.8268959522247314 49 }, 50 { 51 title: 'War Story', 52 released: ISODate('2014-07-30T00:00:00.000Z'), 53 paginationToken: 'CJCdARoGELqvp4MIGgkpAPyQhEcBAAA=', 54 score: 2.8268959522247314 55 }, 56 { 57 title: 'A War', 58 released: ISODate('2015-09-10T00:00:00.000Z'), 59 paginationToken: 'CL2kARoGELqvp4MIGgkpAECNtE8BAAA=', 60 score: 2.8268959522247314 61 } 62 ]