Docs 菜单
Docs 主页
/ / /
Go
/ / /

Retrieve Data

在此页面上

  • Overview
  • 样本数据
  • 查找操作
  • 查找所有文档
  • 查找一个文档
  • 修改行为
  • 聚合操作
  • 聚合(Aggregation)
  • 修改行为
  • 更多信息
  • API 文档

在本指南中,您可以了解如何通过读取操作从 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.
Default: nil
SetLimit()
The maximum number of documents to return.
Default: 0

注意

此选项不适用于 FindOneOptionsFindOne() 方法会在内部使用 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(评分)值介于 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))
}

以下示例将上下文、筛选器和 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))

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

注意

Go Driver 会自动为每个文档的 _id 字段生成唯一的 ObjectId 值,因此您的 ObjectId 值可能不同于上一个代码示例。有关 _id 字段的更多信息,请参阅“插入文档”页面中的 _id 字段部分。

使用聚合操作从 MongoDB 检索和转换数据。使用 Aggregate() 方法执行聚合操作。

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"])
}

要了解有关如何构建聚合管道的更多信息,请参阅 MongoDB 服务器手册中的聚合页面。

有关查找操作的可运行示例,请参阅以下用法示例:

要了解有关提到的操作的更多信息,请参阅以下指南:

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

计算文档