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)) }
{"name":"Kale Tabbouleh","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans."} {"name":"Herbed Whole Branzino","description":"Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4."}
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)) }
{"name":"Shepherd's Pie","description":"A vegetarian take on the classic dish that uses lentils as a base. Serves 2."} {"name":"Garlic Butter Trout","description":"Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2."}
タームを除外した検索
テキスト クエリから除外するタームまたはフレーズごとに、マイナス記号 を先頭に持つタームまたはフレーズを 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)) }
{"name":"Kale Tabbouleh","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans."}
関連性でソート
テキストクエリは、各結果がクエリフィルター内の string にどの程度一致するかを示す数値テキスト スコアを割り当てます。出力にテキスト スコアを表示するには、プロジェクションを使用して textScoreメタデータを取得します。textScoreメタデータで並べ替えを指定することで、テキスト スコアを降順で並べ替えることができます。
例
次の例では、次のアクションが実行されます。
「ベクトル」タームを含む説明に対して、テキスト クエリを実行します
テキスト スコアに基づいて、結果を降順で並べ替えます
最終出力ドキュメントには フィールドと フィールドのみが含まれます
namescore
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)) }
{"name":"Green Curry","score":0.8999999999999999} {"name":"Kale Tabbouleh","score":0.5625} {"name":"Shepherd's Pie","score":0.5555555555555556}
集計
また、$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":"Kale Tabbouleh","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans."} {"name":"Herbed Whole Branzino","description":"Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4."}
関連性でソート
次の例では、次のアクションが実行されます。
「ベクトル」タームを含む説明に対して、テキスト クエリを実行します
テキスト スコアに基づいて、結果を降順で並べ替えます
最終出力ドキュメントには フィールドと フィールドのみが含まれます
namescore
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)) }
{"name":"Green Curry","score":0.8999999999999999} {"name":"Kale Tabbouleh","score":0.5625} {"name":"Shepherd's Pie","score":0.5555555555555556}
詳細情報
上記で説明されている操作の詳細については、次のガイドを参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。