Docs 菜单

Retrieve Data

在本指南中,您可以了解如何通过读取操作从 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)

提示

不存在的数据库和集合

如果执行写操作时不存在必要的数据库和集合,服务器会隐式创建这些数据库和集合。

每份文件都描述了客户订购的茶叶品种、评级和订购日期。这些项目分别对应 itemratingdate_ordered 字段。

使用查找操作从 MongoDB 中检索数据。查找操作由 Find()FindOne() 方法组成。

Find() 方法需要您传递 Context 类型和查询筛选器。该方法以 Cursor 类型返回所有符合筛选条件的文档。

有关使用 Find() 方法的示例,请参阅本页的查找示例部分。要了解如何使用游标访问数据,请参阅从游标访问数据指南。

FindOne() 方法需要您传递 Context 类型和查询过滤器。该方法以 SingleResult 类型返回与过滤器匹配的第一个文档

有关使用 FindOne() 方法的示例,请参阅本页的查找示例部分。有关使用 FindOne() 和使用特定 ObjectId 值进行查询的示例,请参阅本页的按 ObjectId 查找 ObjectId 示例部分。

要了解如何访问来自 SingleResult 类型的数据,请参阅 BSON 指南中的解组

您可以分别传入 FindOptionsFindOneOptions 类型,以修改 Find()FindOne() 的行为。如果不指定任何选项,驱动程序将使用每个选项的默认值。

可以使用以下方法配置这两种类型中的常用选项:

方法
说明

SetCollation()

The type of language collation to use when sorting results.
默认值:nil

SetLimit()

The maximum number of documents to return.
默认值:0
This option is not available for FindOneOptions. The FindOne() method internally uses SetLimit(-1).

SetProjection()

The fields to include in the returned documents.
默认值:nil

SetSkip()

The number of documents to skip.
默认值: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(评分)值介于 59(不含)之间的文档

  • 对匹配的文档按 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"}

此示例定义了一个值为 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 值匹配

  • 仅投影匹配文档的 ItemRating 字段

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() 方法执行聚合操作。

Aggregate() 方法需要您传递 Context 类型和聚合管道。聚合管道定义了如何通过多个阶段转换数据。其中一些阶段包括文档匹配、字段重命名和值的分组。

此方法将返回 Cursor(游标)类型的结果文档。如果省略 $match 阶段,管道将继续使用集合中的所有文档。

要了解如何访问游标中的数据,请参阅访问游标中的数据

Aggregate() 方法可以选择采用 AggregateOptions 类型,该类型表示可用于修改其行为的选项。如果不指定任何选项,驱动程序将使用每个选项的默认值。

AggregateOptions 类型允许您使用以下方法配置选项:

方法
说明

SetAllowDiskUse()

Whether to write to temporary files.
默认值: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.
默认值:false

SetCollation()

The type of language collation to use when sorting results.
默认值:nil

SetMaxAwaitTime()

The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query.
默认值:nil

SetComment()

An arbitrary string or document that allows you to trace the operation through the database profiler, currentOp, and logs.
默认值:""

SetHint()

The index to use to scan for documents to retrieve.
默认值: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 文档: