Docs Menu
Docs Home
/
MongoDB Atlas
/ / / /

結果のページ分割

項目一覧

  • 使用法
  • Considerations
  • 参照点の取得
  • 構文
  • 出力
  • 特定の参照点の後の検索
  • searchAfter 構文
  • 出力
  • 特定の参照点の前の検索
  • searchBefore 構文
  • searchBefore 出力
  • searchSequenceToken クエリ
  • 後続のsearchAfterおよびsearchBeforeクエリ

MongoDB 6.0.13 + または7.0.5 + を実行している Atlas クラスターでは、 Atlas Search を使用して、 $searchクエリ結果を参照点の後、または前に順番に取得します。 $search searchAfterまたはsearchBeforeオプションを使用して結果を順番に走査し、アプリケーション内に「次のページ」と「前のページ」関数を構築します。

ページ分割された結果を検索するには、次の手順を実行します。

  1. クエリを実行したいフィールドにインデックスを作成します。

  2. 参照点を返す$searchクエリを実行します。 詳しくは、「 参照点を取得する 」を参照してください。

  3. 後続の$searchクエリで参照点を使用して、結果内に次または前のドキュメント セットを検索します。

    • "Next Page" 関数を構築するための結果の検索の詳細については、「特定の参照点の後の検索 」を参照してください。

    • 「前のページ」関数を構築するための結果の検索の詳細については、「特定の参照点の前の検索 」を参照してください。

    • 結果のページに移動するには、 $skip$limit$search searchAfterまたはsearchBeforeオプションと組み合わせて使用します。 たとえば、ページ3からページ5に移動し、1 ページあたり10の結果に移動するには、次の操作を実行します。

      1. ページ3の最後の結果の参照点を持つsearchAfterを使用して結果を取得します(結果30 )。

      2. ページ4の10結果(結果31 - 40 )をスキップするには$skipを使用し、結果を10ドキュメントに制限するには、 $limitを使用します。

      3. ページ5の結果を返します(結果41 - 50 )。

      ここで、 searchAfterオプションとともに$skipを使用すると、クエリが最適化され、結果の1ページのみをスキップできます( 10ドキュメント)。 一方、 $search searchAfterオプションなしで$skipを使用すると、クエリは4ページの結果( 40ドキュメント)をスキップします。 詳しくは、「 searchAfter$skipを使用してページ2からページ5に移動する 」を参照してください。

複数のドキュメントが同じ値を持つフィールドでソートすると、同順位となります。 MongoDBでは、関連付けられたクエリ結果の順序が保証されていないため、 searchAftersearchBefore を使用すると重複や不整合が発生する可能性があります。決定的な検索動作を確保するには、次の原則を適用します。

  • 関連性スコアが同値になるのを防ぐために、クエリを一意のフィールドでソートします。

  • 非 一意のフィールドで主にソートする場合は、タイブレークとして機能するために一意のフィールドに セカンダリ ソート句を追加 します。

  • クエリ結果を不変フィールドでソートします。 Atlas Search は、最初のクエリと後続のクエリの間にコレクションに加えた更新を反映します。 updated_time などの可変フィールドでソートし、最初と 2 番目のクエリの間にコレクションを更新すると、Atlas Search は同じドキュメントの順序付け方法が異なる場合があります。

不変または一意のフィールドでクエリ結果を並べ替える方法については、「 Atlas Search結果の並べ替え 」を参照してください。

特定の時点でクエリ結果を検索するには、 $searchクエリで参照点を指定する必要があります。 参照点を検索するには、 ステージの後の$meta searchSequenceToken$projectステージで$search キーワード を使用します。

searchSequenceToken 構文
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オプションを使用して、アプリケーション内で「前のページ」機能を構築できます。 「前のページ」機能を構築するには、以下を組み合わせます。

  • $searchオプションを使用した ステージsearchBefore

  • $limit ステージ

  • toArray()メソッドとreverse()メソッド。

これを証明するために、このページの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}

Atlas Search では、指定されたトークンに先行する結果内のドキュメントが逆の順序で返されます。 Atlas Search では、searchSequenceToken $project$searchステージの後の ステージで を指定したため、結果内のドキュメントの生成されたトークンも返されます(11 行に表示されているように)。これらのトークンは、同じセマンティクスを持つ別のクエリの参照ポイントとして使用できます。

次の例えでは、動的マッピングを持つdefaultという名前の Atlas Search インデックスがあるsample-mflix.moviesコレクションを使用します。 コレクションをロードしてインデックスを作成すると、コレクションに対して次のクエリを実行できます。

次のクエリでは、次のパイプライン ステージを使用します。

  • $search 必要に応じて、次の操作を実行します。

    • コレクションのtitleフィールドでwarというタームを検索します。

    • 最初にスコアで結果を並べ替え、次にreleasedフィールドの値で並べ替え、スコアが同一のドキュメントの昇順で結果を並べ替えます。

  • $limitステージを使用して、結果を10ドキュメントに制限します。

  • $project ステージでは、次を実行できます。

    • titlereleasedフィールドと フィールドのみを含めます。

    • 次のフィールドを追加します。

      • 各ドキュメントの base64 でエンコードされたトークンを含むpaginationTokenという名前のフィールド。

      • 各ドキュメントの関連性スコアを含むscoreという名前のフィールド。

1db.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が結果に返したトークンに置き換えます。

次のクエリでは、同じセマンティクスを持つ別のクエリのトークンを使用して、指定されたトークンの前後でページ分割された結果を検索します。 例のsearchSequenceTokenクエリを実行した場合、結果に含まれるドキュメントのトークンが異なる場合があります。 このセクションのクエリ内のトークンを、クエリ結果で返されたトークンに置き換えてください。

クエリは、次のパイプライン ステージを使用します。

  • $search ステージでは、次を実行できます。

    • Atlas Search の結果から、 titleフィールドでwarというタームを見つけるドキュメントを検索します。

    • 最初にスコアで結果を並べ替え、次にreleasedフィールドの値で並べ替え、スコアが同一のドキュメントの昇順で結果を並べ替えます。

  • $limitステージを使用して、結果を10ドキュメントに制限します。

  • $project ステージでは、次を実行できます。

    • titlereleasedドキュメントには フィールドと フィールドのみを含めます。

    • 次のフィールドを追加します。

      • 各ドキュメントの base64 でエンコードされたトークンを含むpaginationTokenという名前のフィールド。

      • 各ドキュメントの関連性スコアを含むscoreという名前のフィールド。

次のクエリは、指定された参照ポイントのtitleフィールドにwarというタームを含む Atlas Search 結果内のドキュメントをリクエストします。 searchSequenceTokenクエリ結果の最後のドキュメントに関連付けられたトークン( 58行)を参照ポイントとして、結果内の次の10ドキュメントを検索します。

1db.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ドキュメントを結果から検索します。

1db.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()メソッドとともに使用して、「前のページ」のような関数を構築します。

1db.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]

戻る

4. 結果をカウントする