检索数据
概述
在本指南中,您可以了解如何通过读取操作从 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()
的行为。如果不指定任何选项,驱动程序将使用每个选项的默认值。
可以使用以下方法配置这两种类型中的常用选项:
方法 | 说明 |
---|---|
SetCollation() | 对结果进行排序时要使用的语言排序规则类型。 默认: nil |
SetLimit() | 要返回的最大文档数。 默认: 0 注意此选项不适用于 |
SetProjection() | 要包含在返回的文档中的字段。 默认: nil |
SetSkip() | 要跳过的文档数量。 默认: 0 |
SetSort() | 对匹配文档排序的字段和排序类型。您可以指定升序或降序排序。 默认:无 |
查找示例
以下示例将上下文、筛选器和 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)) }
查找一个示例
以下示例将上下文、筛选器和 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))
按对象 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))
注意
Go Driver 会自动为每个文档的 _id
字段生成唯一的 ObjectId
值,因此您的 ObjectId
值可能不同于上一个代码示例。有关 _id
字段的更多信息,请参阅“插入文档”页面中的 _id 字段部分。
聚合操作
使用聚合操作从 MongoDB 检索和转换数据。使用 Aggregate()
方法执行聚合操作。
聚合(Aggregation)
Aggregate()
方法需要您传递 Context
类型和聚合管道。聚合管道定义了如何通过多个阶段转换数据。其中一些阶段包括文档匹配、字段重命名和值的分组。
该方法以Cursor
类型返回结果文档。如果省略$match阶段,管道将继续使用集合中的所有文档。
要了解如何访问游标中的数据,请参阅访问游标中的数据。
修改行为
Aggregate()
方法可以选择采用 AggregateOptions
类型,该类型表示可用于修改其行为的选项。如果不指定任何选项,驱动程序将使用每个选项的默认值。
AggregateOptions
类型允许您使用以下方法配置选项:
方法 | 说明 |
---|---|
SetAllowDiskUse() | 是否写入到临时文件。 默认: false |
SetBatchSize() | 每个批次中待返回的文档数量。 默认:无 |
SetBypassDocumentValidation() | 是否允许写入选择退出文档级验证。 默认: false |
SetCollation() | 对结果进行排序时要使用的语言排序规则类型。 默认: nil |
SetMaxTime() | 查询在服务器上运行的最长时间。 默认: nil |
SetMaxAwaitTime() | 服务器等待新文档以满足可追加游标查询的最长时间。 默认: nil |
SetComment() | 任意字符串,可帮助通过数据库分析器、currentOp 和日志跟踪操作。 默认: "" |
SetHint() | 用于扫描待检索文档的索引。 默认: nil |
SetLet() | 指定聚合表达式的参数,将变量与查询文本分开,从而提高了命令的易读性。 默认:无 |
例子
以下示例传递了上下文和聚合管道,该管道会执行以下操作:
按订购的商品对评论进行分组
计算每个列项的平均评分
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"]) }
要了解有关如何构建聚合管道的更多信息,请参阅 MongoDB 服务器手册中的聚合页面。
更多信息
有关查找操作的可运行示例,请参阅以下用法示例:
要了解有关提到的操作的更多信息,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: