Docs Menu
Docs Home
/ / /
Rust ドライバー
/ / /

クエリ テキスト

このガイドでは、 Rustドライバーを使用してテキスト クエリを実行する方法を学習できます。テキストクエリを使用すると、string 値を持つフィールドを効率的にクエリできます。

重要

MongoDBテキスト クエリは、より強力な Atlas Search 機能とは異なります。詳しくは、Atlas Search のドキュメントを参照してください。

このガイドには、次のセクションが含まれています。

  • 例のサンプル データ では、テキスト クエリの例で使用されるサンプルデータが提示されます

  • テキストインデックスでは、文字列値フィールドにテキスト インデックスを作成する方法について説明します。

  • テキストクエリ では、さまざまな検索条件でテキストクエリを実行する方法について説明します

  • 集計では、集計パイプラインを使用してテキストクエリを実行する方法について説明します

  • 追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します

このガイドの例では、 menuコレクション内のドキュメントのモデルとして、次の Dish構造体を使用します。

#[derive(Serialize, Deserialize, Debug)]
struct Dish {
name: String,
description: String,
}

例では、レストランで注文できるメニューを説明する次のサンプルドキュメントを使用します。

{ "name": "Shepherd’s Pie", "description": "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." },
{ "name": "Green Curry", "description": "A flavorful Thai curry, made vegetarian with tofu. Vegetarian and vegan friendly." },
{ "name": "Herbed Branzino", "description": "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." },
{ "name": "Kale Tabbouleh", "description": "A bright, herb-based salad. A perfect starter for vegetarians and vegans." },
{ "name": "Garlic Butter Trout", "description": "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }

テキストクエリを実行する前に、コレクションにテキストインデックスを作成する必要があります。テキストインデックスは、テキストクエリを実行できる string または string 配列のフィールドを指定します。

このガイドの例では、 menuコレクション内のドキュメントの descriptionフィールドに対してテキスト クエリを実行します。descriptionフィールドでテキストクエリを有効にするには、次のコードに示すように テキストインデックスを作成します。

let index = IndexModel::builder()
.keys(doc! { "description": "text" })
.build();
let idx_res = my_coll.create_index(index).await?;

テキスト クエリは、インデックスフィールドの値に指定されたタームまたはフレーズを含むドキュメントを検索します。タームは、空白文字を除外する文字のシーケンスです。フレーズは、任意の数の空白文字を含むタームのシーケンスです。

テキストクエリを実行するには、クエリフィルターに $text 評価クエリ演算子を含め、その後に $searchフィールドを含めます。$text 演算子は、テキストインデックス作成されたフィールドに対してテキストクエリを実行することを指定します。$searchフィールドは、テキスト インデックス付きフィールドで検索するタームまたはフレーズを指定します。

テキストクエリのフィルターは次の形式を使用します 。

let filter = doc! { "$text": { "$search": "<search term or phrase>" } };

タームを検索するには、クエリフィルターでタームを string として指定します。 複数のタームを検索するには、各タームをスペースで区切ります。

注意

複数のタームを検索する場合、 find()メソッドは、テキストインデックス付きフィールドに少なくとも 1 つのタームが含まれているドキュメントを返します。

たとえば、検索タームが"one two three"の場合、MongoDB は、インデックス付きフィールドに"one""two""three" 、またはこれらのタームが 1 つ以上含まれているドキュメントを返します。

次の例では、 descriptionフィールドに"herb"というタームが含まれているドキュメントを検索します。

let filter = doc! { "$text": { "$search": "herb" } };
let mut cursor = my_coll.find(filter).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }
Dish { name: "Herbed Branzino", description: "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." }

Tip

検索タームが "herb" であっても、テキストクエリは、descriptionフィールドに "herbs" が含まれるドキュメントにも一致します。これは、 MongoDBテキストインデックスが類似単語を一致させるために接尾辞の語幹を使用するためです。MongoDB がタームを一致させる方法の詳細については、サーバー マニュアルの「インデックス エントリ」を参照してください。

フレーズを検索するには、クエリフィルターでエスケープされた引用符を含むフレーズを指定します。

let filter = doc! { "$text": { "$search": "\"<some phrase>\"" } };

フレーズの前後にエスケープされた引用符を追加しない場合、検索はターム検索を実行します。

次の例では、 descriptionフィールドにフレーズ"serves 2"が含まれているドキュメントを検索します。

let filter = doc! { "$text": { "$search": "\"serves 2\"" } };
let mut cursor = my_coll.find(filter).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Shepherd's Pie", description: "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." }
Dish { name: "Garlic Butter Trout", description: "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }

テキスト クエリから除外するタームまたはフレーズを指定するには、クエリフィルターの先頭にマイナス記号を付けます。

let filter = doc! { "$text": { "$search": "<term> -<excluded term>" } };

重要

検索から他のタームを除外するには、少なくとも 1 つのタームまたはフレーズを検索する必要があります。 タームのみを除外する場合、検索ではドキュメントは返されません。

次の例では、 descriptionフィールドに用語"vegan"が含まれているが、 "tofu"という用語は含まれていないドキュメントを検索します。

let filter = doc! { "$text": { "$search": "vegan -tofu" } };
let mut cursor = my_coll.find(filter).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }

テキストクエリは、各結果がクエリフィルター内の string にどの程度一致するかを示す数値テキスト スコアを割り当てます。テキスト スコアが高いほど、結果のクエリに関する関連性が高くなります。出力にテキスト スコアを表示するには、プロジェクションを使用してメタデータから textScoreフィールドを取得します。textScoreメタデータフィールドで並べ替えを指定することで、テキスト スコアを降順で並べ替えることができます。

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

  • descriptionフィールドに"vegetarian"というタームが含まれているドキュメントを検索します

  • 結果を テキスト スコアの降順でソートします

  • 出力にname フィールドと フィールドのみが含まれますscore

let filter = doc! { "$text": { "$search": "vegetarian" } };
let sort = doc! { "score": { "$meta": "textScore" } };
let projection =
doc! {
"_id": 0,
"name": 1,
"score": { "$meta": "textScore" }
};
let doc_coll: Collection<Document> = my_coll.clone_with_type();
let mut cursor = doc_coll.find(filter)
.sort(sort)
.projection(projection)
.await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)})
Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)})
Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})

$match集計ステージに $text 評価クエリ演算子を含めることで、集計パイプラインでテキストクエリを実行できます。

次のセクションでは、find() メソッドの代わりに集計パイプラインを使用してテキスト クエリを実行する方法を示します。

次の例では、集計を使用して、 descriptionフィールドに"herb"というタームが含まれるドキュメントを検索します。

let match_stage = doc! { "$match": { "$text": { "$search": "herb" } } };
let mut cursor = my_coll.aggregate([match_stage]).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"_id": ObjectId("..."), "name": String("Kale Tabbouleh"), "description": String("A bright, herb-based salad. A perfect starter for vegetarians and vegans.")})
Document({"_id": ObjectId("..."), "name": String("Herbed Branzino"), "description": String("Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.")})

この例では、集計を使用して次のアクションを実行しています。

  • descriptionフィールドに"vegetarian"というタームが含まれているドキュメントを検索します

  • 結果を テキスト スコアの降順でソートします

  • 出力にname フィールドと フィールドのみが含まれますscore

let match_stage = doc! { "$match": { "$text": { "$search": "vegetarian" } } };
let sort_stage = doc! { "$sort": { "score": { "$meta": "textScore" } } };
let proj_stage =
doc! { "$project": {
"_id": 0,
"name": 1,
"score": { "$meta": "textScore" }
} };
let pipeline = [match_stage, sort_stage, proj_stage];
let mut cursor = my_coll.aggregate(pipeline).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)})
Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)})
Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})

find()メソッドを使用する実行可能な例については、「 複数のドキュメントの検索 」の使用例を参照してください。

このガイドの操作の詳細については、次のドキュメントを参照してください。

このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。

戻る

オープンChange Streams

項目一覧