検索テキスト
項目一覧
Overview
このガイドでは、Rust ドライバーを使用してテキスト検索を実行する方法を学習できます。 テキスト検索では、string 値を持つフィールドを効率的にクエリできます。
重要
MongoDB テキスト検索は、より強力な Atlas Search 機能と異なります。 詳しくは、 Atlas Search のドキュメントを参照してください。
このガイドには、次のセクションが含まれています。
例のサンプル データ では、テキスト検索の例で使用されるサンプル データが
テキストインデックスでは、文字列値フィールドにテキスト インデックスを作成する方法について説明します。
テキスト検索 では、さまざまな検索条件でテキスト検索を実行する方法について説明します
集計では、集計パイプラインを使用してテキスト検索を実行する方法について説明します
追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します
サンプルデータの例
このガイドの例では、 menu
コレクション内のドキュメントのモデルとして、次の Dish
構造体を使用します。
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." }
Text Index
テキスト検索を実行する前に、コレクションにテキスト インデックスを作成する必要があります。 テキスト インデックスは、テキスト検索を実行できる 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()
メソッドを使用する実行可能な例については、「 複数のドキュメントの検索 」の使用例を参照してください。
このガイドの操作の詳細については、次のドキュメントを参照してください。
テキスト インデックス(サーバー マニュアルの参照)
$text (サーバー マニュアルを参照してください)
サーバー マニュアルの$meta
API ドキュメント
このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。