文档菜单
文档首页
/ / /
Go 驱动
/ / /

搜索文本

本页内容

  • 概述
  • 示例数据
  • 文本索引
  • 文本搜索
  • 按术语搜索
  • 按短语搜索
  • 排除术语搜索
  • 按相关性排序
  • 聚合
  • 匹配搜索词
  • 按相关性排序
  • 更多信息
  • API文档

在本指南中,您可以学习如何运行文本搜索.

重要

MongoDB文本搜索与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)

每个文档包含餐厅菜单中菜肴的 namedescription

提示

不存在的数据库和集合

当您执行写操作而所需的数据库和集合不存在时,服务器会隐式创建它们。

在运行文本搜索之前,您必须创建一个文本索引。文本索引指定了要运行文本搜索的字符串或字符串数组字段。

以下部分中的示例在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>"}}}}

要搜索一个词,请在查询过滤器中将词指定为字符串。要搜索多个词,请在字符串中用空格分隔每个词。

注意

当搜索多个词时,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))
}
{"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."}

提示

尽管搜索词是 "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))
}
{"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."}

对于您想从文本搜索中排除的每个术语或短语,请将带有连字符前缀的术语或短语作为字符串指定在查询过滤器中。

重要

如果您想排除搜索中的术语,则必须至少搜索一个术语。如果您不搜索任何术语,则 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))
}
{"name":"Kale Tabbouleh","description":"A bright, herb-based salad. A perfect starter for vegetarians and vegans."}

文本搜索为每个结果分配一个数值文本得分,以指示每个结果与查询过滤器中的字符串匹配的紧密程度。要显示输出中的文本得分,请使用投影来检索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}

有关所提操作的更多信息,请参阅以下指南

  • 指定查询

  • 排序结果

  • 指定要返回的字段

  • 文本索引

  • $text

  • $meta

  • 聚合

  • 索引

要了解更多关于本指南中讨论的任何方法或类型的信息,请参阅以下 API 文档

返回

指定要返回的字段