Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/

配置增删改查操作

在本指南中,您可以学习;了解如何使用Go驾驶员来配置读取和写入操作。

您可以通过设置读取偏好(read preference)控制驾驶员路由读取操作的方式。您还可以通过设置读关注(read concern)写关注(write concern)来控制驾驶员处理数据一致性和持久性的方式。读关注指定执行读操作时数据所需的持久性级别,写入关注指定驾驶员如何等待副本集的写入操作确认。

您可以在以下级别设置写关注、读关注和读取偏好选项:

  • 客户端级别,除非被覆盖,否则将为所有操作执行设置默认值

  • 会话级别

  • 事务级别

  • 数据库级别

  • 集合级别

前面的列表还指示了选项设置的优先级递增顺序。示例,如果为ACID 事务设立读关注(read concern),它将覆盖为客户端设立的读关注(read concern)。

写关注(write concern)描述了副本集集中承载数据的节点的数量,这些节点必须在操作返回为成功之前确认写入操作,例如插入或更新。默认下,如果只有主节点 (primary node in the replica set)副本集成员确认,则写入操作成功。

MongoDB Go驱动程序提供了 writeconcern包,它允许您为副本集指定写关注(write concern)。通过将 WriteConcern 类型的实例传递给 SetWriteConcern() 方法来设置写关注(write concern)。WriteConcern 类型提供以下方法来选择常见的写关注(write concern)规范:

方法
说明

Custom()

The client requests acknowledgement that write operations propagate to tagged members of a mongod instance. For more information, see the Write Concern specification.

Parameter: tag (string)

Journaled()

The client requests acknowledgement that the replica set has written the changes to the on-disk journal. For more information, see the Write Concern specification.

Parameter: none

Majority()

The client requests acknowledgement that write operations propagate to the majority of data-bearing voting members. For more information, see the Write Concern specification.

Parameter: none

Unacknowledged()

The client requests requests no acknowledgment of write operations. For more information, see the Write Concern specification for w: 0.

Parameter: none

W1()

The client requests acknowledgement that the replica set has written the changes to memory on one node, such as the standalone mongod or the primary in a replica set. For more information, see the Write Concern specification for w: 1.

Parameter: none

提示

写关注超时

您无法在 WriteConcern实例上设立超时。相反,请在创建上下文时使用 WithTimeout() 方法在操作级别设立超时。要学习;了解更多信息,请参阅《连接选项》指南中的 限制服务器执行时间

如果需要更专门的写关注,则您可以自行定义 WriteConcern 结构文本。您可以在 WriteConcern 结构中设置以下字段:

字段
说明

W

Specifies the number of mongod instances or tagged members that write operations must propagate to for acknowledgement. Common values include 1, 0, and "majority".

Type: string or int

Journal

Specifies whether the replica set must write the changes to the on-disk journal for acknowledgement.

Type: bool

提示

或者,您可以在连接字符串中指定写关注(write concern)。 有关更多信息,请参阅服务器手册中有关写关注选项的条目。

以下代码展示了如何在客户端和集合级别指定不同的写入关注。客户端级写关注(write concern)请求两个副本集成员的确认,并将日志设置为 false。集合级别的写关注(write concern)请求大多数副本集成员的确认。

uri := "mongodb://<hostname>:<port>"
journal := false
cliWC := &writeconcern.WriteConcern{
W: 2,
Journal: &journal,
}
clOpts := options.Client().ApplyURI(uri).SetWriteConcern(cliWC)
client, err := mongo.Connect(clOpts)
...
collWC := writeconcern.Majority()
collOpts := options.Collection().SetWriteConcern(collWC)
coll := client.Database("db").Collection("myColl", collOpts)

读关注选项可以让您确定客户端从查询中返回哪些数据。默认的读关注级别为“本地”,这意味着客户端会返回实例的最新数据,但不保证该数据已写入大多数副本集成员。

MongoDB Go驱动程序提供了 readconcern包,可让您指定副本集的读关注(read concern)。通过将 ReadConcern 类型的实例传递给 SetReadConcern() 方法来设置读关注(read concern)。ReadConcern 类型具有以下方法来指定读关注(read concern):

方法
说明

Available()

查询从实例返回数据,但不保证数据已写入大多数副本集成员。 有关更多信息,请参阅读关注规范。

Linearizable()

该查询返回的数据反映了以写关注(write concern)majority 发出并在读操作开始之前确认的所有成功写入。有关更多信息,请参阅读关注规范。

Local()

查询会返回实例的最新数据。 有关更多信息,请参阅读关注规范。

Majority()

该查询返回确认已写入副本集中大多数成员的实例的最新数据。 有关更多信息,请参阅读关注规范。

Snapshot()

该查询返回特定时间点mongod实例中数据的完整副本。此选项仅适用于多文档事务中的操作。有关更多信息,请参阅读关注规范。

以下代码显示了如何指定“majority”的读关注(read concern)。然后,代码会选择带有此选项的Collection

rc := readconcern.Majority()
opts := options.Collection().SetReadConcern(rc)
database := client.Database("db")
coll := database.Collection("myCollection", opts)

读取偏好选项指定 MongoDB 客户端如何将读取操作路由到副本集成员。默认情况下,应用程序将其读取操作定向到副本集中的主节点。

读取偏好由读取偏好模式和可选的标签集列表maxStalenessSeconds选项和对冲读选项组成。

MongoDB Go驱动程序提供了 readpref包,它允许您指定副本集的读取偏好(read preference)。通过将 ReadPref 类型的实例传递给 SetReadPreference() 方法来设置读取偏好(read preference)。ReadPref 类型具有以下方法来指定读取偏好(read preference):

方法
说明

Nearest()

客户端根据指定的延迟阈值从符合条件的随机副本集成员中读取。有关更多信息,请参阅读取偏好服务器手册条目。

Primary()

客户端从当前副本集主节点读取。 有关更多信息,请参阅MongoDB Server手册中的读取偏好条目。

PrimaryPreferred()

客户端会从可用的主节点 (primary node in the replica set)节点中读取数据。如果主节点 (primary node in the replica set)不可用,则操作将从从节点(secondary node from replica set)成员读取。有关更多信息,请参阅读取偏好服务器手册条目。

Secondary()

客户端从副本集的从节点读取。 有关更多信息,请参阅MongoDB Server手册中的读取偏好条目。

SecondaryPreferred()

如果有一个或多个可用的从节点,客户端会从从节点(secondary node from replica set)读取。如果从节点不可用,则操作将从主节点 (primary node in the replica set)成员读取。有关更多信息,请参阅读取偏好服务器手册条目。

提示

或者,您可以在连接字符串中指定读取偏好(read preference)。 有关详细信息,请参阅有关“读取偏好选项”的服务器手册条目

以下代码显示如何将读取偏好指定到从节点的读取。然后代码使用此选项选择 Database

rp := readpref.Secondary()
opts := options.Database().SetReadPreference(rp)
database := client.Database("db", opts)

如果某些写入操作由于网络或服务器错误而失败,Go驾驶员会自动重试一次。

在使用 options.Client 结构体创建新客户端时,您可以通过将 RetryReadsRetryWrites 选项设置为 False 来显式禁用可重试读取或可重试写入。

以下示例使用 ClientOptions setter 函数为客户端禁用可重试读取和写入:

// Defines the client options
clientOps := options.Client().
ApplyURI(uri).
SetRetryWrites(false).
SetRetryReads(false)
// Creates a new client using the specified options
client, err := mongo.Connect(clientOps)
if err != nil {
panic(err)
}

要学习;了解有关支持的可重试读取操作的更多信息,请参阅MongoDB Server手册中的可重试读取。要学习;了解有关支持的可重试写入操作的更多信息,请参阅MongoDB Server手册中的可重试写入。

您可以指定排序规则来修改读取和写入操作的行为。排序规则是一设立特定于语言的字符串比较规则,例如字母大小写和重音符号规则。

默认下, MongoDB使用二进制排序规则对字符串进行排序。此默认规则使用 ASCII 标准 字符值对字符串进行比较和排序。语言和区域设置具有与 ASCII 标准不同的特定字符排序约定,您可以选择在操作中应用一设立不同的排序规则。

您可以在以下级别指定排序规则:

  • 集合:为集合上的操作设置默认规则。您无法为现有集合定义排序规则。

  • 索引:为使用索引的操作设置排序规则。

  • 操作:设置操作的排序规则并覆盖任何继承的排序规则。

要指定排序规则,请创建一个 Collation对象。您必须定义 Collation对象的 Locale字段,但所有其他字段都是可选的。示例,以下代码示例指定具有 "en_US"区域设置设置排序规则的 Collation对象:

myCollation := &options.Collation{Locale: "en_US"}

有关Collation 对象字段的完整列表,请访问 Collation API 文档 。要查看所有支持的区域设置以及Locale字段的默认值,请访问支持的语言和区域设置。

创建新的集合或视图时,可以应用排序规则。 这定义了对该集合或视图调用的任何操作的默认排序规则。 通过CreateCollectionOptionsCreateViewOptions对象设置排序规则。 然后,将选项对象作为参数调用CreateCollection()CreateView()方法。

以下示例创建了一个名为books的新集合,并指定了具有"fr"区域设置的默认排序规则。 Strength排序规则字段的值为1 ,用于忽略字母重音的差异。

myCollation := &options.Collation{Locale: "fr", Strength: 1}
opts := options.CreateCollection().SetCollation(myCollation)
err := db.CreateCollection(context.TODO(), "books", opts)
if err != nil {
panic(err)
}

如果您在books集合上调用使用排序规则的操作,则该操作将使用创建集合示例中指定的默认排序规则。

假设books集合包含以下文档:

{"name" : "Emma", "length" : "474"}
{"name" : "Les Misérables", "length": "1462"}
{"name" : "Infinite Jest", "length" : "1104"}
{"name" : "Cryptonomicon", "length" : "918"}
{"name" : "Ça", "length" : "1138"}

注意

要学习;了解如何插入文档,请参阅插入文档。

以下示例使用Find()方法返回name值按字母顺序位于"Infinite Jest"之前的所有文档:

filter := bson.D{{"name", bson.D{{"$lt", "Infinite Jest"}}}}
cursor, err := coll.Find(context.TODO(), filter)
if err != nil {
panic(err)
}
var results []bson.D
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))
}
{"name":"Emma","length":"474"}
{"name":"Cryptonomicon","length":"918"}
{"name":"Ça","length":"1138"}

如果代码未指定默认的books 排序规则,则 Find() 方法将遵循默认的二进制排序规则规则来确定 "Infinite Jest" 之前的 name 值。这些规则将以“Ç”开头的单词放在以“I”开头的单词之后。输出如下所示:

{"name":"Emma","length":"474"}
{"name":"Cryptonomicon","length":"918"}

要学习;了解有关 Find() 方法的更多信息,请参阅查找文档。

在集合上创建新索引时,可以应用排序规则。 该索引会将文档的有序表示形式存储在集合中,因此 MongoDB 实例不会在内存中执行排序操作。

要在操作中使用索引,操作必须使用与索引中指定的排序规则相同的排序规则。 此外,请确保包含排序规则的索引涵盖该操作。 通过IndexOptions对象设置排序规则,并将该对象作为参数传递给CreateOne()方法。

创建books集合并应用默认排序规则后(如创建集合示例部分所示),您无法更改集合的默认排序规则。 但是,您可以使用不同的排序规则为集合创建索引。

以下示例使用CreateOne()方法在name字段上创建升序索引,并指定具有"en_US"区域设置的新排序规则:

myCollation := &options.Collation{Locale: "en_US"}
opts := options.Index().SetCollation(myCollation)
indexModel := mongo.IndexModel{
Keys: bson.D{{"name", 1}},
Options: opts,
}
name, err := coll.Indexes().CreateOne(context.TODO(), indexModel)
if err != nil {
panic(err)
}
fmt.Println("Name of Index Created: " + name)
Name of Index Created: name_1

从集合中读取、更新和删除文档的操作可以使用排序规则。 将排序规则应用于操作会覆盖之前为集合定义的任何默认排序规则。

如果对操作应用的新排序规则不同于索引的排序规则,则无法使用该索引。 因此,该操作的性能可能不如索引所涵盖的操作。 有关索引未涵盖的排序操作缺点的更多信息,请参阅使用索引对查询结果进行排序。 有关支持排序规则的操作列表,请参阅MongoDB 手册

您可以使用支持排序规则的操作来更新和查询books集合中的文档。

以下示例使用Find()方法返回length值大于"1000"的文档。 NumericOrdering排序规则字段的值为true ,以确保值按数字顺序而不是字母顺序排序:

filter := bson.D{{"length", bson.D{{"$gt", "1000"}}}}
myCollation := &options.Collation{Locale: "en_US", NumericOrdering: true}
opts := options.Find().SetCollation(myCollation)
cursor, err := coll.Find(context.TODO(), filter, opts)
if err != nil {
panic(err)
}
var results []bson.D
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))
}
{"name":"Les Misérables","length":"1462"}
{"name":"Infinite Jest","length":"1104"}
{"name":"Ça","length":"1138"}

如果代码未指定将 NumericOrdering字段设立为 true 的排序规则,则同一 Find() 操作会将 length 值作为字符串进行比较。在这种情况下,输出如下所示:

{"name":"Emma","length":"474"}
{"name":"Les Misérables","length":"1462"}
{""name":"Infinite Jest","length":"1104"}
{"name":"Cryptonomicon","length":"918"}
{"name":"Ça","length":"1138"}

要学习;了解有关Find()方法的更多信息,请参阅《查找文档》指南。

要学习;了解有关本指南中讨论的概念的更多信息,请访问以下手册页面:

要进一步了解本指南中讨论的方法,请参阅以下 API 文档:

后退

复合运算符

在此页面上