AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

結果のページ分割

MongoDB 7.0.5+を実行中クラスターでは、MongoDB 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 )。

      ここで、$skip を searchAfter オプションとともに使用すると、クエリが最適化され、結果の 1 ページのみをスキップします(10件のドキュメント)。比較すると、$search searchAfter オプションを使用せずに $skip を使用すると、クエリは結果の 4 ページ(40件のドキュメント)をスキップします。詳細については、「searchAfter と $skip を使用してページ 2 からページ 5 へジャンプする」をご覧ください。

  • 複数のドキュメントが同じ値を持つフィールドでソートすると、同点となります。Mongo DBは、結び付けられたクエリ結果の順序を保証しません。searchAfter と searchBefore を使用すると、重複や不整合が発生する可能性があります。関連性スコアの同点を減らすために、次の原則を応用します。

    • 関連性スコアの同点を防ぐために、クエリを一意のフィールドで並べ替えます。例については、 「スコアと一意のフィールドによる並べ替え」を参照してください。

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

  • クエリ間でドキュメントを更新または削除すると、結果順序の不整合が発生する可能性があります。決定的な検索する動作をサポートするには、次の原則を適用します。

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

    • 専用の検索ノードを配置し、searchScore 、結果をソートする場合は、以下を考慮してください。

      • デフォルトでは、MongoDB Search は bm25 類似度アルゴリズムを使用してドキュメントにスコアを付けます。このアルゴリズムは、MongoDB Search ノード上のドキュメント全体のコーパスに対する用語の頻度を計算します。各 MongoDB Search ノードは変更ストリームから独立して複製されるため、このコーパスは MongoDB Search ノード間で異なる場合があります。その結果、同じクエリが異なる MongoDB Search ノードにルーティングされると、異なる bm25 スコアが返される可能性があります。後続のクエリは、配置が専用の MongoDB Search ノード を使用する場合、または読み込み設定 が secondary または nearest に設定されている場合、異なる MongoDB Search ノードにルーティングされる可能性が高くなります。

      • 以降のクエリでコンシステントなスコアが得られるようにするには、フィールドを MongoDB Search のstringまたはautocomplete型としてインデックス化するときにsimilarity.type プロパティをstableTfl あるいはboolean に設定します。これにより、text、phrase、queryString、autocomplete 演算子は、インデックス付きフィールドのクエリの関連性スコアを計算するためにstableTflまたはboolean類似度アルゴリズムを使用するようになります。これらのアルゴリズムは、すべての MongoDB Search ノードで一貫してスコアを計算します。詳細については、「スコアの詳細」を参照してください。

  • ページネーション中に検索結果をカウントするには、最初の クエリまたは別の $search$searchMetaクエリで カウント オプションを使用します。この方法は、$count ステージの後に$search ステージを使用するよりも効率的です。

    count オプションは検索条件に一致するドキュメントの合計数を返すため、ページ分割された結果を生成している場合は、後のクエリで count オプションを使用する必要がありません。$searchメインの クエリとは別にカウントするには、$searchMeta オプションを指定したcount ステージを使用します。

    検索結果をカウントすると、パフォーマンスに影響する可能性があります。count オプションは必要な場合にのみ使用してください。例、最初のページの検索結果を取得する場合などです。

特定の時点でクエリ結果を検索するには、 $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"
10 }
11 },
12 ...
13 },
14 {
15 "$project": {
16 "paginationToken" : { "$meta" : "searchSequenceToken" }
17 },
18 ...
19}]

searchSequenceTokenは、結果内の各ドキュメントに対して base 64でエンコードされたトークンを生成します。 トークンの長さは、クエリのソートオプションで指定されたフィールドの数に応じて増加します。 トークンはデータベースのスナップショットには関連付けられていません。

クエリで sort オプションを指定しない限り、結果内のドキュメントはデフォルトの順序でソートされます。結果の並べ替えの詳細については、「 MongoDB検索結果の並べ替え 」を参照してください。

参照点を検索するには、 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"
11 }
12 },
13 ...
14 },
15 "$project": {
16 "paginationToken" : { "$meta" : "searchSequenceToken" }
17 },
18 ...
19}]

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

クエリで sort オプションを指定しない限り、結果内のドキュメントはデフォルトの順序でソートされます。結果の並べ替えの詳細については、「 MongoDB検索結果の並べ替え 」を参照してください。

参照点の前を検索するには、 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"
11 }
12 },
13 ...
14 },
15 "$project": {
16 "paginationToken" : { "$meta" : "searchSequenceToken" }
17 },
18 ...
19}]

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

次の例では、db.collection.aggregate() $searchメソッドを使用して、 sample_mflix データベースに対して クエリを実行します。最初のクエリ例では、参照点の検索方法を示します。後続のクエリ例では、この参照点の前後のページの追加結果を検索するためにこの参照点を使用します。

mongosh: でこれらの例クエリを実行するには、次のようにします。

  1. sample_mflix.movies コレクションをロードする

  2. 動的マッピングを使用して pagination-tutorialインデックスを作成します。インデックスの作成方法については、「MongoDB Search インデックスの管理」を参照してください。

  3. mongosh を使用してクラスターに接続し、sample_mflixデータベースに切り替えます

注意

デフォルトでは 、 MongoDB Search は結果内のドキュメントを、ドキュメントの関連性スコアでソートします。結果内の複数のドキュメントのスコアが同じである場合、 MongoDB Search は任意の順序付けられた結果を返します。特定の順序でドキュメントを返すには、クエリで一意のフィールドreleased を指定して結果をソートします。

最初のページの結果を検索し、後続のクエリのためのトークンまたは参照点を検索します。

サンプル クエリでは、次のパイプライン ステージを使用して最初のページの結果を取得し、後続のクエリのトークンまたは参照点を取得します。

パイプラインステージ
説明
  • テキスト演算子を使用して、 titleフィールドにsummerを含むタイトルを検索します。

  • 並べ替えオプションを使用して、 releasedフィールド値で結果を昇順に並べ替えます。

結果を10ドキュメントに制限します。

ドキュメントのtitle 、 released 、 genresフィールドのみが結果に含まれます。 このクエリは、結果内の各ドキュメントに次のフィールドも追加します。

  • paginationTokenは、後続のクエリで参照点として使用できるトークンです。

  • scoreは、結果内のドキュメントの関連性スコアです

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken": { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])

注意

検索結果をカウントする

ページ分割中に検索結果をカウントするには、$searchMeta クエリを実行し、count オプションを使用します。これにより、検索条件に一致するドキュメントの総数を含むメタデータドキュメントが返されます。

次のサンプルクエリは、titleフィールド内の summer期間を持つドキュメントの合計数を取得します。

db.movies.aggregate([
{
"$searchMeta": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"count": {
"type": "lowerBound",
"threshold": 5000
}
}
}
])

結果を検索して、アプリケーションに「次のページ」のような機能を構築します。

追加の結果を検索するには、結果を検索したい時点より後の参照点を指定します。

サンプル クエリでは、次のパイプライン ステージを使用して、同じタームの前のクエリからsearchSequenceTokenによって生成されたトークンを使用して、2 ページの結果を検索します。

パイプラインステージ
説明
  • テキスト演算子を使用して、 titleフィールドにsummerを含むタイトルを検索します。

  • ページsearchAfter を検索する、ページ分割トークンを生成するために実行したクエリの結果内の 10 番目のドキュメントに関連付けられたページ分割トークンとともに オプションを使用して、結果内の 101 番目のドキュメント以降のドキュメントを返します。

  • 並べ替えオプションを使用して、 releasedフィールド値で結果を昇順に並べ替えます。

結果を10ドキュメントに制限します。

ドキュメントのtitle 、 released 、 genresフィールドのみが結果に含まれます。 また、結果内の各ドキュメントに次のフィールドも追加されます。

  • paginationTokenは、後続のクエリで参照点として使用できるトークンです。

  • scoreは、結果内のドキュメントの関連性スコアです

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchAfter": "COwRGgkpAPQV0hQAAAA=",
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])

結果を検索して、アプリケーションに「前のページ」のような機能を構築します。

以前の結果を検索するには、結果を検索したい時点より前の参照点を指定します。

このサンプル クエリでは、次のパイプライン ステージを使用して、前のクエリで同じタームのsearchSequenceTokenによって生成されたトークンを使用して、最初のページの 結果を返します。

パイプラインステージ
説明
  • テキスト演算子を使用して、 titleフィールドにsummerを含むタイトルを検索します。

  • MongoDB Search の結果で、searchBefore オプションと、searchAfter を使用してページ 2 を検索するために実行したクエリの結果の 11 番目のドキュメントに関連付けられたページ分割トークンを使用して、ドキュメント 1 から 10 を返します。

  • 並べ替えオプションを使用して、 releasedフィールド値で結果を昇順に並べ替えます。

結果を10ドキュメントに制限します。

ドキュメントのtitle 、 released 、 genresフィールドのみが結果に含まれます。 また、結果内の各ドキュメントに次のフィールドも追加されます。

  • paginationTokenは、後続のクエリで参照点として使用できるトークンです。

  • scoreは、結果内のドキュメントの関連性スコアです

注意

デフォルトでは 、 MongoDB Search は、参照点の前に結果を検索するためのトークンを指定するクエリに対して、逆の順序で結果を返します。ドキュメントを順番に返すには、クエリではtoArray()とJavaScript reverse() メソッドが使用されます。

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchBefore": "CMwSGgkpAECHcCIAAAA=",
"sort": { "released": 1 }
}
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
]).toArray().reverse()

結果を検索して、アプリケーションでページスキップを可能にする機能を構築します。

結果をスキップして 2 ページから 5 ページへジャンプするには、searchSequenceToken が生成するトークンを使用して、結果を取得する基準点を指定し、その後、結果で 20 件のドキュメントをスキップします。

サンプル クエリでは、前のクエリで同じタームのsearchSequenceTokenによって生成されたトークンを使用し、 $skip } ステージと$limitステージを使用して、次のパイプライン ステージを使用してページ5の結果に移動します。

パイプラインステージ
説明
  • テキスト演算子を使用して、 titleフィールドにsummerを含むタイトルを検索します。

  • 並べ替えオプションを使用して、 releasedフィールド値で結果を昇順に並べ替えます。

  • searchAfter を使用してページ 2 を検索するために実行したクエリで生成されたページ区切りトークンを使用して指定された 20 番目より後のドキュメントを返します。

指定された参照点の後の結果内の 20 件のドキュメントをスキップします。この参照点は、searchAfter を使用してページ 2 を検索するために実行したクエリの結果内の 20 番目のドキュメントに関連付けられたトークンです。

結果を10ドキュメントに制限します。

ドキュメントのtitle 、 released 、 genresフィールドのみが結果に含まれます。 また、結果内の各ドキュメントに次のフィールドも追加されます。

  • paginationTokenは、後続のクエリで参照点として使用できるトークンです。

  • scoreは、結果内のドキュメントの関連性スコアです

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"text": {
"path": "title",
"query": "summer"
},
"searchAfter": "COwRGgkpAPQV0hQAAAA=",
"sort": { "released": 1 }
}
},
{
"$skip": 20
},
{
"$limit": 10
},
{
"$project": {
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : { "$meta" : "searchSequenceToken" },
"score": { "$meta": "searchScore" }
}
}
])

MongoDB Search ファセット では searchSequenceToken を使用します。

MongoDB Search facet(MongoDB Search 演算子)を使用して結果をグループ化するには、すべての stringフィールドをtoken タイプとしてインデックス必要があります。次のクエリを実行し、moviesコレクションの genresフィールドで結果をグループ化するには、インデックスが次の例のようになっている必要があります。

{
"mappings": {
"dynamic": true,
"fields": {
"genres": {
"type": "token"
}
}
}
}
}

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

パイプラインステージ
説明
  • facet(MongoDB検索演算子)コレクターを使用して、titleフィールドに summer を含むタイトルを検索します。

  • facetsオプションを使用して、各ジャンルの結果内の映画の合計数を検索します。

searchSequenceToken オプションを使用して生成された結果内の各ドキュメントのトークンを保存するためにpaginationTokenフィールドを追加します。

結果を10ドキュメントに制限します。

次のフィールドを返します。

  • docs フィールド。これには結果内のドキュメントのtitle 、 released 、 genresフィールドとpaginationTokenフィールドのみが含まれます。

  • meta フィールド。これには、 $$SEARCH_META変数に保存されている各ジャンルの結果内の映画の総数が含まれます。

db.movies.aggregate([
{
"$search": {
"index": "pagination-tutorial",
"facet": {
"operator": {
"text": {
"path": "title",
"query": "summer"
}
},
"facets": {
"genresFacet": {
"type": "string",
"path": "genres"
}
}
}
}
},
{
"$addFields": {
"paginationToken" : { "$meta" : "searchSequenceToken" }
}
},
{ "$limit": 10 },
{
"$facet": {
"docs": [
{ "$project":
{
"_id": 0,
"title": 1,
"released": 1,
"genres": 1,
"paginationToken" : 1
}
}
],
"meta": [
{ "$replaceWith": "$$SEARCH_META" },
{ "$limit": 1 }
]
}
},
{
"$set": {
"meta": {
"$arrayElemAt": ["$meta", 0]
}
}
}
])