“文档” 菜单
文档首页
/ / /
Go 驱动程序
/ / /

检索数据

在此页面上

  • 概述
  • 样本数据
  • 查找操作
  • 查找所有文档
  • 查找一个文档
  • 修改行为
  • 聚合操作
  • 聚合(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()
对结果进行排序时要使用的语言排序规则类型。
默认: nil
SetLimit()
要返回的最大文档数。
默认: 0

注意

此选项不适用于 FindOneOptionsFindOne() 方法会在内部使用 SetLimit(-1)

SetProjection()
要包含在返回的文档中的字段。
默认: nil
SetSkip()
要跳过的文档数量。
默认: 0
SetSort()
对匹配文档排序的字段和排序类型。您可以指定升序或降序排序。
默认:无

以下示例将上下文、筛选器和 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()
是否写入到临时文件。
默认: 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 文档:

← 计算文档