检索数据
概述
在本指南中,您可以学习如何使用读取操作从您的 MongoDB 集合中检索数据。
读取操作允许您执行以下操作
示例数据
本指南中的示例使用以下内容Tea
结构体作为 tea
集合中文档的模型
type Tea struct { Item string `bson:"item,omitempty"` Rating int32 `bson:"rating,omitempty"` DateOrdered time.Time `bson:"date_ordered,omitempty"` }
要运行本指南中的示例,请使用以下代码片段将以下文档加载到 db
数据库中的 tea
集合中
coll := client.Database("db").Collection("tea") docs := []interface{}{ Tea{Item: "Masala", Rating: 10, DateOrdered: time.Date(2009, 11, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 7, DateOrdered: time.Date(2009, 11, 18, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 9, DateOrdered: time.Date(2009, 11, 12, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 8, DateOrdered: time.Date(2009, 12, 1, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 10, DateOrdered: time.Date(2009, 12, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Hibiscus", Rating: 4, DateOrdered: time.Date(2009, 12, 18, 0, 0, 0, 0, time.Local)}, } result, err := coll.InsertMany(context.TODO(), docs)
提示
不存在的数据库和集合
在执行写操作时,如果必要的数据库和集合不存在,服务器会隐式创建它们。
每个文档都描述了客户订购的茶品种、他们的评分和订单日期。这些描述对应于 item
、rating
和 date_ordered
字段。
查找操作
使用 查找操作 从 MongoDB 中检索数据。查找操作包括 Find()
和 FindOne()
方法。
查找所有文档
Find()
方法期望你传递一个 Context
类型和一个查询过滤器。该方法返回所有匹配过滤器的文档,以 Cursor
类型返回。
有关使用 Find()
方法的示例,请参阅本页的 查找示例 部分。有关如何使用游标访问数据的说明,请参阅从游标访问数据 指南。
查找单个文档
FindOne()
方法期望你传递一个 Context
类型和一个查询过滤器。该方法返回第一个匹配过滤器的文档,以 SingleResult
类型返回。
有关使用 FindOne()
方法的示例,请参阅本页的 查找单个示例 部分。有关使用 FindOne()
并通过特定的 ObjectId
值进行查询的示例,请参阅本页的 通过 ObjectId 查找单个示例 部分。
有关如何从 SingleResult
类型访问数据的说明,请参阅 BSON 指南中的 反序列化 部分。
修改行为
您可以通过传递一个FindOptions
和一个FindOneOptions
类型来修改Find()
和FindOne()
的行为。如果您没有指定任何选项,驱动程序将使用每个选项的默认值。
您可以使用以下方法配置这两种类型中常用的选项
方法 | 描述 |
---|---|
SetCollation() | 在排序结果时使用的语言排序类型。 默认: nil |
SetLimit() | 要返回的最大文档数。 默认: 0 此选项对于 FindOneOptions 不可用。内部使用FindOne() 的SetLimit(-1) 。 |
SetProjection() | 要在返回的文档中包含的字段。 默认: nil |
SetSkip() | 要跳过的文档数。 默认: 0 |
SetSort() | 用于对匹配的文档进行排序的字段和类型。您可以指定升序或降序排序。 默认: none |
查找示例
以下示例将上下文、过滤器以及FindOptions
传递给Find()
方法,该方法执行以下操作
匹配
rating
值在5
和9
之间(不包含)的文档按
date_ordered
升序排序匹配的文档
filter := bson.D{ {"$and", bson.A{ bson.D{{"rating", bson.D{{"$gt", 5}}}}, bson.D{{"rating", bson.D{{"$lt", 9}}}}, }}, } sort := bson.D{{"date_ordered", 1}} opts := options.Find().SetSort(sort) // Retrieves documents that match the filter and prints them as structs cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []Tea 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)) }
{"item":"Sencha","rating":7,"date_ordered":"2009-11-18T05:00:00Z"} {"item":"Masala","rating":8,"date_ordered":"2009-12-01T05:00:00Z"}
找到一个示例
以下示例将上下文、过滤器以及FindOneOptions
传递给FindOne()
方法,该方法执行以下操作
匹配日期值为2009年11月30日或之前的文档
跳过前两个匹配的文档
filter := bson.D{{"date_ordered", bson.D{{"$lte", time.Date(2009, 11, 30, 0, 0, 0, 0, time.Local)}}}} opts := options.FindOne().SetSkip(2) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err := coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Masala","rating":9,"date_ordered":"2009-11-12T05:00:00Z"}
通过ObjectId查找示例
此示例定义了一个值为ObjectId
类型的id
变量,并使用id
指定查询过滤器。该过滤器匹配一个具有与_id
字段值相对应的id
变量的文档。此示例基于其_id
值查询以下文档
{ _id: ObjectId('65170b42b99efdd0b07d42de'), item: "Hibiscus", rating : 4, date_ordered : 2009-12-18T05:00:00.000+00:00 }
以下代码将过滤器和一个FindOneOptions
实例作为参数传递给FindOne()
方法以执行以下操作
匹配具有指定
ObjectId
值的文档仅投影匹配文档的
Item
和Rating
字段
id, err := primitive.ObjectIDFromHex("65170b42b99efdd0b07d42de") if err != nil { panic(err) } // Creates a filter to match a document that has the specified // "_id" value filter := bson.D{{"_id", id}} opts := options.FindOne().SetProjection(bson.D{{"item", 1}, {"rating", 1}}) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err = coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Hibiscus","rating":4}
注意
Go驱动程序会自动为每个文档的_id
字段生成一个唯一的ObjectId
值,因此您的ObjectId
值可能与前面的代码示例不同。有关_id
字段的更多信息,请参阅[插入文档](/docs/drivers/go/current/fundamentals/crud/write-operations/insert/#std-label-golang-insert-id)页面上的_id Field
部分。
聚合操作
使用 聚合操作 从 MongoDB 中检索和转换数据。使用 Aggregate()
方法执行聚合操作。
聚合
Aggregate()
方法期望你传递一个 Context
类型和一个 聚合管道。聚合管道定义了如何通过阶段转换数据。一些阶段包括匹配文档、重命名字段和分组值。
该方法返回结果文档的 Cursor
类型。如果你省略了 $match 阶段,管道将使用集合中的所有文档继续执行。
要了解如何从游标访问数据,请参阅从游标访问数据。
修改行为
Aggregate()
方法可选地接受一个 AggregateOptions
类型,它表示可以用来修改其行为的选项。如果你没有指定任何选项,驱动程序将使用每个选项的默认值。
AggregateOptions
类型允许你使用以下方法配置选项
方法 | 描述 |
---|---|
SetAllowDiskUse() | 是否写入临时文件。 默认: false |
SetBatchSize() | 每个批次返回的文档数量。 默认: none |
SetBypassDocumentValidation() | 是否允许写入操作免于文档级验证。 默认: false |
SetCollation() | 在排序结果时使用的语言排序类型。 默认: nil |
SetMaxTime() | 查询在服务器上运行的最大时间。 默认: nil |
SetMaxAwaitTime() | 服务器等待新文档以满足tailable cursor查询的最大时间。 默认: nil |
SetComment() | 任意字符串,有助于通过数据库分析器、currentOp和日志跟踪操作。 默认值: "" |
SetHint() | 用于扫描以检索文档的索引。 默认: nil |
SetLet() | 指定聚合表达式的参数,通过将变量从查询文本中分离出来提高命令的可读性。 默认: none |
示例
以下示例传递一个上下文和一个执行以下操作的聚合管道:
按项目顺序对评论进行分组
计算每个项目的平均评分
groupStage := bson.D{ {"$group", bson.D{ {"_id", "$item"}, {"average", bson.D{ {"$avg", "$rating"}, }}, }}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage}) if err != nil { panic(err) } // Prints the average "rating" for each item var results []bson.M if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Printf("%v had an average rating of %v \n", result["_id"], result["average"]) }
Sencha had an average rating of 8.5 Hibiscus had an average rating of 4 Masala had an average rating of 9
要了解更多关于如何构建聚合管道的信息,请参阅MongoDB服务器手册中的聚合。
更多信息
有关find操作的运行示例,请参阅以下用法示例
要了解更多关于所提操作的信息,请参阅以下指南
API 文档
要了解更多关于本指南中讨论的任何方法或类型,请参阅以下API文档