検索テキスト
Overview
このガイドでは、 テキスト検索を実行する方法を説明します。
重要
MongoDB テキスト検索はAtlas Search と異なります。
サンプル データ
このガイドの例では、 menu
コレクション内のドキュメントのモデルとして、次の Dish
構造体を使用します。
type Dish struct { Name string Description string }
このガイドの例を実行するには、次のスニペットを使用してサンプルデータをdb.menu
コレクションにロードします。
coll := client.Database("db").Collection("menu") docs := []interface{}{ Dish{Name: "Shepherd’s Pie", Description: "A vegetarian take on the classic dish that uses lentils as a base. Serves 2."}, Dish{Name: "Green Curry", Description: "A flavorful Thai curry, made vegetarian with fried tofu. Vegetarian and vegan friendly."}, Dish{Name: "Herbed Whole Branzino", Description: "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4."}, Dish{Name: "Kale Tabbouleh", Description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans."}, Dish{Name: "Garlic Butter Trout", Description: "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2."}, } result, err := coll.InsertMany(context.TODO(), docs)
各ドキュメントには、レストランのメニューのname
とdescription
が含まれています。
Tip
存在しないデータベースとコレクション
書き込み操作を実行するときに必要なデータベースとコレクションが存在しない場合は、サーバーが暗黙的にそれらを作成します。
Text Index
テキスト検索を実行する前に、テキストインデックスを作成する必要があります。 テキストインデックスは、テキスト検索を実行する string または string 配列フィールドを指定します。
次のセクションの例では、 menu
コレクション内のドキュメントのdescription
フィールドでテキスト検索を実行します。 description
フィールドでテキスト検索を有効にするには、次のスニペットを使用して テキスト インデックス を作成します。
model := mongo.IndexModel{Keys: bson.D{{"description", "text"}}} name, err := coll.Indexes().CreateOne(context.TODO(), model) if err != nil { panic(err) } fmt.Println("Name of index created: " + name)
テキスト検索
テキスト検索では、テキスト インデックス フィールドにタームまたはフレーズを含むドキュメントが検索されます。 タームは、空白文字を除外する文字のシーケンスです。 フレーズは、任意の数の空白文字を含むタームのシーケンスです。
テキスト検索を実行するには、 $text
評価クエリ演算子を使用し、クエリフィルターで$search
フィールドを使用します。 $text
演算子は、テキスト インデックス フィールドに対してテキスト検索を実行します。 $search
フィールドは、テキスト インデックス フィールドで検索するテキストを指定します。
テキスト検索のクエリフィルターは次の形式を使用します。
filter := bson.D{{"$text", bson.D{{"$search", "<text to search>"}}}}
タームで検索
タームを検索するには、クエリフィルターでタームを string として指定します。 複数のタームを検索するには、string 内にスペースで各タームを区切ります。
注意
複数のタームを検索する場合、 Find()
メソッドは、テキスト インデックス フィールドに少なくとも 1 つのタームを含むドキュメントを返します。
例
次の例では、"herb" というタームを含む説明のテキスト検索を実行します。
filter := bson.D{{"$text", bson.D{{"$search", "herb"}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []Dish if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
Tip
検索用語は「herb」でしたが、MongoDB テキストインデックスでは類似単語を一致させるために接尾辞の語幹が使用されるため、 メソッドは「herb」を含む説明にも一致します。 MongoDB がタームを一致させる方法の詳細については、「インデックス エントリ 」を参照してください。
フレーズで検索
フレーズを検索するには、クエリフィルターの string として、エスケープされた引用符を含むフレーズを指定します。 フレーズの前後にエスケープされた引用符を追加しない場合、 Find()
メソッドはターム検索を実行します。
Tip
エスケープされた引用符は、バックスラッシュ文字とそれに続くdouble引用符文字です。
例
次の例では、「services 2」というフレーズを含む説明のテキスト検索を実行します。
filter := bson.D{{"$text", bson.D{{"$search", "\"serves 2\""}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []Dish if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
タームを除外した検索
テキスト検索から除外する用語またはフレーズごとに、クエリ フィルターの string としてマイナス記号を先頭に付けた用語またはフレーズを指定します。
重要
検索からタームを除外する場合は、少なくとも 1 つのタームを検索する必要があります。 タームを検索しない場合、 Find()
メソッドはドキュメントを返しません。
例
次の例では、"VEgan" という用語を含むが "toft" という用語は含まない説明のテキスト検索を実行します。
filter := bson.D{{"$text", bson.D{{"$search", "vegan -tofu"}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []Dish if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
関連性でソート
テキスト検索では、数値テキスト スコアが割り当てられ、各結果がクエリフィルター内の string にどの程度一致するかを示します。 出力にテキスト スコアを表示するには、プロジェクションを使用してtextScore
メタデータを取得します。 textScore
メタデータで並べ替えを指定すると、テキスト スコアを降順で並べ替えることができます。
例
次の例では、次のアクションが実行されます。
「ベクトル」というタームを含む説明のテキスト検索を実行します
テキスト スコアに基づいて、結果を降順で並べ替えます
最終出力ドキュメントには フィールドと フィールドのみが含まれます
name
score
filter := bson.D{{"$text", bson.D{{"$search", "vegetarian"}}}} sort := bson.D{{"score", bson.D{{"$meta", "textScore"}}}} projection := bson.D{{"name", 1}, {"score", bson.D{{"$meta", "textScore"}}}, {"_id", 0}} opts := options.Find().SetSort(sort).SetProjection(projection) cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
集計
また、集計パイプラインでテキスト検索を実行するには、 $matchステージに$text
評価クエリ演算子を含めます。
検索タームに一致
次の例では、"herb" というタームを含む説明のテキスト検索を実行します。
matchStage := bson.D{{"$match", bson.D{{"$text", bson.D{{"$search", "herb"}}}}}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage}) if err != nil { panic(err) } var results []Dish if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
関連性でソート
次の例では、次のアクションが実行されます。
「ベクトル」というタームを含む説明のテキスト検索を実行します
テキスト スコアに基づいて、結果を降順で並べ替えます
最終出力ドキュメントには フィールドと フィールドのみが含まれます
name
score
matchStage := bson.D{{"$match", bson.D{{"$text", bson.D{{"$search", "vegetarian"}}}}}} sortStage := bson.D{{"$sort", bson.D{{"score", bson.D{{ "$meta", "textScore" }}}}}} projectStage := bson.D{{"$project", bson.D{{"name", 1}, {"score", bson.D{{ "$meta", "textScore" }}}, {"_id", 0}}}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, sortStage, projectStage}) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
詳細情報
上記で説明されている操作の詳細については、次のガイドを参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。