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

$rankFunction(集計)

重要

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

8.0 からアップグレードする場合、$rankFusion クエリの実行を一時停止する必要がある場合があります。

$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 つのパイプラインが含まれている必要があります。すべてのパイプラインは同じコレクションで動作する必要があり、一意の名前が必要です。

For more information on input pipeline restrictions, see Input Pipelines and Input Pipeline Names.

combination

オブジェクト

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

combination.
weights

オブジェクト

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

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

scoreDetails

ブール値

Default is false. Specifies if $rankFusion computes and populates the $scoreDetails metadata field for each output document. See scoreDetails for more information on this field.

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

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

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

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

注意

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

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

タイプ
ステージ

検索ステージ

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

順序付けステージ

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

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

  • 次の順序付けられたステージのいずれかから始まります。

  • 明示的な $sort ステージが含まれています。

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メタデータフィールドを表示するには、次のいずれかを行う必要があります。

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

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

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

フィールド
説明

value

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

description

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

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 型のインデックスを作成します。

The following index definition automatically indexes all the dynamically indexable fields in the collection for running $search queries against the indexed fields.

検索インデックス
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 ドキュメントを出力します

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

次の Movie クラスは、sample_mflix.movies コレクション内のドキュメントをモデル化します。

public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

注意

パスカルケースの ConventionPack

このページのC# クラスはプロパティ名にパスカルケースを使用していますが、MongoDB コレクションのフィールド名はキャメルケースを使用しています。この違いを考慮するために、アプリケーションが起動する際に次のコードを使用してConventionPackを登録してください。

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

To use the MongoDB .NET/C# driver to add a $rankFusion stage to an aggregation pipeline, call the Unwind() method on a PipelineDefinition object.

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

var collection = client.GetDatabase("sample_mflix").GetCollection<Movie>("movies");
var index = new BsonDocument
{
{ "mappings", new BsonDocument
{
{ "dynamic", true }
}
}
};
collection.SearchIndexes.CreateOne(index, "default");

The following example creates a pipeline stage that executes two pipelines, searchPlot and searchGenre, that perform $search operations by using the default search index. The $rankFusion stage then ranks the search results based on each $search pipeline's assigned weight and returns the ordered results. The pipeline includes the scoreDetails field in the return documents by enabling the ScoreDetails option in the RankFusionOptions instance passed to the RankFusion() method.

var searchPipelines = new Dictionary<string, PipelineDefinition<Movie, Movie>>
{
{
"searchPlot",
new EmptyPipelineDefinition<Movie>()
.Search(
Builders<Movie>.Search.Text(Builders<Movie>.SearchPath.Single(m => m.Plot), "space"))
},
{
"searchGenre",
new EmptyPipelineDefinition<Movie>()
.Search(
Builders<Movie>.Search.Text(Builders<Movie>.SearchPath.Single(m => m.Genres), "adventure"))
}
};
var weights = new Dictionary<string, double>
{
{ "searchPlot", 0.4 },
{ "searchGenre", 0.6 }
};
var pipeline = new EmptyPipelineDefinition<Movie>()
.RankFusion(searchPipelines, weights, new RankFusionOptions<Movie> { ScoreDetails = true });

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

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

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

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

The following example creates a pipeline stage that executes two pipelines, searchPlot and searchGenre, that perform $search operations by using the default search index. The $rankFusion stage then ranks the search results based on each $search pipeline's assigned weight and returns the ordered results. The $addFields stage includes the scoreDetails field in the return documents. The example then runs the aggregation pipeline:

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;
このページを評価