Docs Menu
Docs Home
/
データベース マニュアル
/ / /

$rankFunction(集計)

重要

$rankFusion MongoDB 8.0 以上を使用する配置でのみ使用できます。

$rankFusion

$rankFusion 最初にすべての入力パイプラインを個別に実行し、次に重複を除外して、入力パイプラインの結果を最終的にランク付けされた結果セットに結合します。

$rankFusion は、入力ドキュメントが入力パイプラインに現れるランクとパイプラインの重み に基づいて、ランク付けされたドキュメントのセットを出力します。このステージでは、 レプリカ ランク 統合アルゴリズムを使用して、入力パイプラインの合計結果をランク付けします。

$rankFusion を使用して、複数の条件に基づいて単一のコレクション内のドキュメントを検索し、指定されたすべての条件で要素が一致する最終順位結果セットを取得します。

このステージの構文は、次のとおりです。

{ $rankFusion: {
input: {
pipelines: {
<myPipeline1>: <expression>,
<myPipeline2>: <expression>,
...
}
},
combination: {
weights: {
<myPipeline1>: <numeric expression>,
<myPipeline2>: <numeric expression>,
...
}
},
scoreDetails: <bool>
} }

$rankFusion は、次のフィールドがあります。

フィールド
タイプ
説明

input

オブジェクト

$rankFusion がランク付けする入力を定義します。

input.pipelines

オブジェクト

そのパイプラインを定義する集計ステージへのパイプライン名とのマップが含まれます。 input.pipelines には少なくとも 1 つのパイプラインが含まれている必要があります。すべてのパイプラインは同じコレクションで動作する必要があり、一意の名前が必要です。

入力パイプラインの制限の詳細については、「 入力パイプライン 入力パイプライン名 」を参照してください。

combination

オブジェクト

任意。 inputパイプラインの結果を組み合わせる方法を定義します。

combination.weights

オブジェクト

任意。 inputパイプライン名から他のパイプラインに対する相対的な重みへのマップが含まれています。各重み値は負でない数(整数、または小数)である必要があります。

重みを指定しない場合、デフォルト値は 1 です。

scoreDetails

ブール値

デフォルトは false です。$rankFusion $scoreDetailsが各出力ドキュメントの メタデータフィールドを計算して入力するかどうかを指定します。このフィールドの詳細については、「 スコアの詳細 」を参照してください。

$rankFusion は 1 つのコレクションでのみ使用できます。この集計ステージは、データベーススコープでは使用できません。

$rankFusion は、最終出力の複数の入力パイプラインにわたる結果の重複を排除します。一意の各入力ドキュメントは、ドキュメントが入力パイプライン出力に表示される回数に関係なく、$rankFusion 出力に最大 1 回表示されます。

inputパイプラインは、選択パイプラインとランク付けパイプラインの両方である必要があります。

選択パイプラインは、検索後に変更を実行せずにコレクションからドキュメントのセットを検索します。 $rankFusion は異なる入力パイプライン間でドキュメントを比較します。このため、すべての入力パイプラインが同じ変更されていないドキュメントを出力する必要があります。

注意

$rankFusion を使用して検索するドキュメントを変更する場合は、$rankFusion ステージの後にそれらの変更を行います。

選択パイプラインには、次のステージのみを含める必要があります。

タイプ
ステージ

検索ステージ

  • (レガシーテキスト検索では $matchを含む)$match

  • $search

  • $vectorSearch

  • $sample

  • $geoNear

    注意

    選択パイプラインで $geoNear を使用する場合、includeLogs または distanceField は指定できません。これらのフィールドはドキュメントを変更するためです。

順序付けステージ

ページネーション ステージ

ランク付けされたパイプラインはドキュメントをソートまたは順序付けします。 $rankFusion は、ランク付けされたパイプライン結果の順序を使用して出力ランキングに影響します。ランク付けされたパイプラインは、次のいずれかの条件を満たす必要があります。

input のパイプライン名は次の制限を満たす必要があります。

  • 空の文字列ではない

  • で開始しないでください $

  • string のどこにも ASCII null 文字区切り文字 \0 を含めることはできません

  • 次を含めることはできません: .

$rankFusion は、 先数ランク統合(RLF)式 に従って結果を並べ替えます。このステージでは、各ドキュメントの SRF スコアが 出力結果の scoreメタデータフィールドに配置されます。 SRF 式では、次の要因を組み合わせてドキュメントをランク付けします。

  • 入力パイプラインへのドキュメントの配置の結果

  • ドキュメントが異なる入力パイプラインに表示される回数

  • 入力パイプラインの weights

例、ドキュメントが複数のパイプライン結果セットでランキングの高い場合、そのドキュメントの SRF スコアは、そのドキュメントが一部の入力パイプラインで同じランキングを使用しているが存在しない(またはランキングが低い場合)よりも高い値になります。他のパイプラインでは

整数ランク統合(SRF)式は、次の 算術操作と同等です。

レプリカランク統合式
クリックして拡大します

注意

この式では、60 はMongoDBによって決定された区別値パラメーターです。

以下の表には、ARF 式が使用する変数が含まれています。

変数
説明

D

操作全体の結果ドキュメントのセット。

d

SRF スコアが計算されるドキュメント。

R

d が表示される入力パイプラインのランクのセット。

r(d)

この入力パイプライン内のドキュメントd のランク。

w

d が表示される入力パイプラインの重み。

合計内の各タームは、input パイプラインのいずれかにおけるドキュメントd の出現を表します。 d の合計 RTF スコアは、d が表示されるすべての入力パイプラインにおけるこれらの各タームの合計です。

1 つの $search と 1 つの $vectorSearch 入力パイプラインを持つ $rankFusionパイプラインステージを考えてみましょう。

すべての入力パイプラインは同じ 3 ドキュメントを出力します(Document1Document2Document3)。

$searchパイプラインは、ドキュメントを次の順序でランク付けします。

  1. Document3

  2. Document2

  3. Document1

$vectorSearchパイプラインは、ドキュメントを次の順序でランク付けします。

  1. Document1

  2. Document2

  3. Document3.

rankFusion は、次の操作を通じて Document1 の SRF スコアを計算します。

RRFscore(Document1) = 1/(60 + search_rank_of_Document1) + (1/(60 + vectorSearch_rank_of_Document1))
RRFscore(Document1) = 1/63 + 1/61
RRFscore(Document1) = 0.0322664585

Document1scoreメタデータフィールドは0.0322664585 です。

scoreDetailstrue に設定すると、$rankFusion は各ドキュメントに対して scoreDetailsメタデータフィールドを作成します。 scoreDetailsフィールドには最終ランキングに関する情報が含まれています。

注意

scoreDetailstrue に設定すると、$rankFusion は各ドキュメントの scoreDetailsメタデータフィールドを設定しますが、scoreDetails メタフィールドは自動的に出力しません。

scoreDetailsメタデータフィールドを表示するには、次のいずれかを行う必要があります。

  • $projectの後に$rankFusion ステージを使用してscoreDetails フィールドをプロジェクト

  • $addFieldsの後に$rankFusion ステージを使用して、パイプライン出力にscoreDetails フィールドを追加する

scoreDetailsフィールドには次のサブフィールドが含まれています。

フィールド
説明

value

このドキュメントの RTF スコアの数値。

description

$rankFusion SRF スコアを計算する方法の説明。

details

このドキュメントを出力する入力パイプラインに関する情報が各配列エントリに含まれている配列。

detailsフィールド内の各配列エントリには、次のサブフィールドが含まれています。

フィールド
説明

inputPipelineName

このドキュメントを出力する入力パイプラインの名前。

rank

入力パイプラインにおけるこのドキュメントのランク。他のパイプラインパイプラインステージ出力で返されるドキュメントがこのパイプラインステージの出力に存在しない場合、ランクは N/A です。

weight

入力パイプラインの重み。

value

任意。入力パイプラインがこのドキュメントに対して { $meta: 'score' } を出力する場合、value には { $meta: 'score' } が含まれます。

description

任意。入力パイプラインがこのドキュメントの scoreDetails の一部として descriptionフィールドを出力する場合、details.description にはそのフィールド値が含まれます。

details

入力パイプラインの scoreDetailsフィールド。入力パイプラインがscoreDetailsフィールドを出力しない場合、このフィールドは空の配列になります。

警告

MongoDB、scoreDetails の特定の出力形式は保証されません。

例、次のコード ブロックは、$search$vectorSearch$match 入力パイプラインを使用した $rankFusion操作の scoreDetailsフィールドを示しています。

{
value: 0.030621785881252923,
description: "value output by reciprocal rank fusion algorithm, computed as sum of weight * (1 / (60 + rank)) across input pipelines from which this document is output, from:"
details: [
{
inputPipelineName: 'search',
rank: 2,
weight: 1,
value: 0.3876491287,
description: "sum of:",
details: [... omitted for brevity in this example ...]
},
{
inputPipelineName: 'vector',
rank: 9,
weight: 3,
value: 0.7793490886688232,
details: [ ]
},
{
inputPipelineName: 'match',
rank: 10,
weight: 1,
details: []
}
]
}

MongoDB は、$rankFusion 操作を既存の集計ステージのセットに変換し、クエリの実行前に出力結果を計算します。 $rankFusion操作の説明結果には、$rankFusion が最終結果を作成するために使用する基礎となる集計ステージの完全な実行が示されています。

この例では、埋め込みとテキスト フィールドを持つコレクションを使用しています。コレクションに searchvectorSearch 型のインデックスを作成します。

次のインデックス定義は、インデックス フィールドに対して$search クエリを実行中ために、コレクション内のすべての動的にインデックス可能なフィールドを自動的にインデックス化します。

検索インデックス
db.embedded_movies.createSearchIndex(
"search_index",
{
mappings: { dynamic: true }
}
)

次のインデックス定義は、そのフィールドに対して クエリを実行中ためのコレクション内の$vectorSearch を含むフィールドをインデックスします。

vectorSearch インデックス
db.embedded_movies.createSearchIndex(
"vector_index",
"vectorSearch",
{
"fields": [
{
"type": "vector",
"path": "<FIELD_NAME>",
"numDimensions": <NUMBER_OF_DIMENSIONS>,
"similarity": "dotProduct"
}
]
}
);

次の集計パイプラインでは、次の入力パイプラインで $rankFusion を使用します。

パイプライン
返されたドキュメントの数
説明

searchOne

20

埋め込みとして指定されたタームの vector タイプとしてインデックス付けされたフィールドでベクトル検索を実行します。クエリは最大 500 の最近傍を考慮しますが、結果は 20 ドキュメントに制限されます。

searchTwo

20

同じタームの全文検索を実行し、結果を 20 ドキュメントに制限します。

1db.embedded_movies.aggregate( [
2 {
3 $rankFusion: {
4 input: {
5 pipelines: {
6 searchOne: [
7 {
8 "$vectorSearch": {
9 "index": "<INDEX_NAME>",
10 "path": "<FIELD_NAME>",
11 "queryVector": <QUERY_EMBEDDINGS>,
12 "numCandidates": 500,
13 "limit": 20
14 }
15 }
16 ],
17 searchTwo: [
18 {
19 "$search": {
20 "index": "<INDEX_NAME>",
21 "text": {
22 "query": "<QUERY_TERM>",
23 "path": "<FIELD_NAME>"
24 }
25 }
26 },
27 { "$limit": 20 }
28 ],
29 }
30 }
31 }
32 },
33 { $limit: 20 }
34] )

この操作は、次のアクションを実行します。

  • input パイプラインを実行します

  • 返された結果を組み合わせます

  • $rankFusionパイプラインの上位 20 結果である最初の 20 ドキュメントを出力します

このページのNode.js の例では、Atlasサンプルデータセットsample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。

MongoDB Node.jsドライバーを使用して $rankFusion ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $rankFusion 演算子を使用します。

次の例を実行中前に、default という名前の Atlas Searchインデックスを作成する必要があります。アプリケーションに次のコードを含めて、moviesコレクションに検索インデックスを作成します。

const index = {
name: "default",
definition: {
mappings: { dynamic: true }
}
}
const result = collection.createSearchIndex(index);

次の例では、2 つのパイプライン(searchPlotsearchGenre $searchを実行し、default 検索インデックスを使用して 操作を実行するパイプラインステージを作成します。次に、$rankFusion ステージは各$search パイプラインに割り当てられた重みに基づいて検索結果をランク付けし、順序付けられた結果を返します。$addFields ステージでは、返されるドキュメントにscoreDetails フィールドが含まれます。次に、この例では集計パイプラインを実行します。

const pipeline = [
{
$rankFusion: {
input: {
pipelines: {
searchPlot: [
{
$search: {
index: "default",
text: { query: "space", path: "plot"}
}
}
],
searchGenre: [
{
$search: {
index: "default",
text: { query: "adventure", path: "genres" }
}
}
]
}
},
combination: { weights: {searchPlot: 0.6, searchGenre: 0.4} },
scoreDetails: true
}
},
{ $addFields: { scoreDetails: { $meta: "searchScoreDetails" } } }
];
const cursor = collection.aggregate(pipeline);
return cursor;

戻る

ログ出力の切り替え

項目一覧