搜索文本
在此页面上
Overview
在本指南中,您可以了解如何运行 文本Atlas Search 。
重要
MongoDB文本Atlas Search与Atlas Search不同。
样本数据
本部分的示例使用以下 Dish
结构作为 menu
集合中文档的模型:
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
(描述)。
提示
不存在的数据库和集合
如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。
Text Index
您必须先创建文本索引,再执行文本搜索。文本索引指定要执行文本搜索的字符串或字符串数组字段。
以下部分中的示例对 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
字段。$text
操作符对文本索引字段执行文本搜索。$search
字段指定要在文本索引字段中搜索的文本。
文本搜索的查询筛选器使用以下格式:
filter := bson.D{{"$text", bson.D{{"$search", "<text to search>"}}}}
按术语搜索
要搜索一个术语,请在查询筛选器中将此术语指定为一个字符串。要搜索多个术语,请在字符串中使用空格分隔每个术语。
注意
搜索多个术语时,Find()
方法会返回文本索引字段中至少包含其中一个术语的文档。
例子
以下示例会对包含术语“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)) }
提示
尽管Atlas Search词语是“herb”,但该方法也会匹配包含“herbs”的描述,因为MongoDB文本索引使用后缀词干来匹配相似单词。 要了解有关 MongoDB 如何匹配术语的更多信息,请参阅索引项。
按短语搜索
要搜索一个短语,请在查询过滤器中将带有转义引号的短语指定为一个字符串。如果不在短语两边添加转义引号,Find()
方法将执行术语搜索。
提示
转义引号是后跟双引号的反斜杠字符。
例子
以下示例对包含短语“serves 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)) }
排除术语搜索
对于要从文本搜索中排除的每个术语或短语,请在查询筛选器中指定以减号为前缀的术语或短语作为字符串。
重要
如果您要从搜索中排除术语,则必须至少搜索一个术语。如果您不搜索任何术语,则 Find()
方法不会返回任何文档。
例子
以下示例对包含“vegan”但不包含“tofu”的描述进行文本搜索:
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)) }
按相关性排序
文本搜索功能将分配一个数字文本分数,以表明每个结果与查询筛选器中的字符串的匹配程度。要在输出中显示文本分数,请使用一个投影检索 textScore
元数据。您可以指定对 textScore
元数据进行排序,以便按降序顺序对文本分数进行排序。
例子
以下示例执行以下动作:
对包含术语“vegetarian”(素食)的描述进行文本搜索
按结果的文本分数的降序顺序对结果进行排序
仅包括最终输出文档中的
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)) }
聚合(Aggregation)
您还可以在 $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)) }
按相关性排序
以下示例执行以下动作:
对包含术语“vegetarian”(素食)的描述进行文本搜索
按结果的文本分数的降序顺序对结果进行排序
仅包括最终输出文档中的
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 文档: