Retrieve Data
Overview
在本指南中,您可以了解如何通过读取操作从 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
类型返回所有符合筛选条件的文档。
查找一个文档
FindOne()
方法需要您传递 Context
类型和查询过滤器。该方法以 SingleResult
类型返回与过滤器匹配的第一个文档。
有关使用 FindOne()
方法的示例,请参阅本页的查找示例部分。有关使用 FindOne()
和使用特定 ObjectId
值进行查询的示例,请参阅本页的按 ObjectId 查找 ObjectId 示例部分。
要了解如何访问来自 SingleResult
类型的数据,请参阅 BSON 指南中的解组。
修改行为
您可以分别传入 FindOptions
和 FindOneOptions
类型,以修改 Find()
和 FindOne()
的行为。如果不指定任何选项,驱动程序将使用每个选项的默认值。
可以使用以下方法配置这两种类型中的常用选项:
方法 | 说明 |
---|---|
| The type of language collation to use when sorting results. 默认值: nil |
| The maximum number of documents to return. 默认值: 0 This option is not available for FindOneOptions . The
FindOne() method internally uses SetLimit(-1) . |
| The fields to include in the returned documents. 默认值: nil |
| The number of documents to skip. 默认值: 0 |
| The field and type of sort to order the matched documents. You can specify an ascending or descending sort. Default: 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()
方法,后者将执行以下操作:
匹配
date_ordered
值在 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"}
按对象 ID 查找一个文档的示例
此示例定义了一个值为 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 Driver 会自动为每个文档的 _id
字段生成唯一的 ObjectId
值,因此您的 ObjectId
值可能不同于上一个代码示例。有关 _id
字段的更多信息,请参阅“插入文档”页面中的 _id 字段部分。
聚合操作
使用聚合操作从 MongoDB 检索和转换数据。使用 Aggregate()
方法执行聚合操作。
聚合(Aggregation)
Aggregate()
方法需要您传递 Context
类型和聚合管道。聚合管道定义了如何通过多个阶段转换数据。其中一些阶段包括文档匹配、字段重命名和值的分组。
此方法将返回 Cursor
(游标)类型的结果文档。如果省略 $match 阶段,管道将继续使用集合中的所有文档。
要了解如何访问游标中的数据,请参阅访问游标中的数据。
修改行为
Aggregate()
方法可以选择采用 AggregateOptions
类型,该类型表示可用于修改其行为的选项。如果不指定任何选项,驱动程序将使用每个选项的默认值。
AggregateOptions
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
| Whether to write to temporary files. 默认值: false |
| The number of documents to return in each batch. Default: none |
| Whether to allow the write to opt-out of document level validation. 默认值: false |
| The type of language collation to use when sorting results. 默认值: nil |
| The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. 默认值: nil |
| An arbitrary string or document that allows you to trace the operation through the database profiler, currentOp, and logs. 默认值: "" |
| The index to use to scan for documents to retrieve. 默认值: nil |
| Specifies parameters for the aggregate expression, which improves command readability by separating the variables from the query text. Default: 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 服务器手册中的聚合页面。
更多信息
有关查找操作的可运行示例,请参阅以下用法示例:
要了解有关提到的操作的更多信息,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: