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
类型返回所有符合筛选条件的文档。
有关使用Find()
方法的示例,请参阅本页的“查找示例”部分。 要学习;了解如何使用游标访问权限数据,请参阅从游标访问数据指南。
查找一个文档
FindOne()
方法需要您传递 Context
类型和查询过滤器。该方法以 SingleResult
类型返回与过滤器匹配的第一个文档。
有关使用 FindOne()
方法的示例,请参阅本页的查找示例部分。有关使用 FindOne()
和使用特定 ObjectId
值进行查询的示例,请参阅本页的按 ObjectId 查找 ObjectId 示例部分。
要了解如何访问来自 SingleResult
类型的数据,请参阅 BSON 指南中的解组。
修改行为
您可以分别传入 FindOptions
和 FindOneOptions
类型,以修改 Find()
和 FindOne()
的行为。如果不指定任何选项,驱动程序将使用每个选项的默认值。
可以使用以下方法配置这两种类型中的常用选项:
方法 | 说明 |
---|---|
SetCollation() | The type of language collation to use when sorting results. Default: nil |
SetLimit() | The maximum number of documents to return. Default: 0 This option is not available for FindOneOptions . The
FindOne() method internally uses SetLimit(-1) . |
SetProjection() | The fields to include in the returned documents. Default: nil |
SetSkip() | The number of documents to skip. Default: 0 |
SetSort() | 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
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
SetAllowDiskUse() | Whether to write to temporary files. Default: false |
SetBatchSize() | The number of documents to return in each batch. Default: none |
SetBypassDocumentValidation() | Whether to allow the write to opt-out of document level validation. Default: false |
SetCollation() | The type of language collation to use when sorting results. Default: nil |
SetMaxTime() | The maximum amount of time that the query can run on the server. Default: nil |
SetMaxAwaitTime() | The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Default: nil |
SetComment() | An arbitrary string to help trace the operation through the database profiler, currentOp and logs. Default: "" |
SetHint() | The index to use to scan for documents to retrieve. Default: nil |
SetLet() | 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 文档: