【翻译】MongoDB指南/CRUD操作(二)

2023-10-07 04:20
-->

【原文地址】https://m.genealogy-computer-tips.com/manual/

MongoDB CRUD操作(二)

主要内容:

更新文档、删除文档、批量写入操作、SQL与MongoDB映射、读隔离(读注意力)、写确认(写注意力)

1 更新文档

1.1 更新

MongoDB 提供了以下更新集合的方法

db.collection.updateOne()

更新与指定过滤器匹配的文档。即使过滤器匹配多个文档,也只会更新一个文档。

3.2版本的新功能。

db.collection.updateMany()

更新与指定过滤器匹配的所有文档。

3.2版本的新功能。

db.collection.replaceOne()

替换与指定过滤器匹配的文档。即使过滤器匹配多个文档,也只会更新一个文档。

3.2版本的新功能。

db.collection.update()

更新或替换与指定过滤器匹配的文档,或更新与指定过滤器匹配的所有文档。

默认只更新一份文档。要更新多个文档,请使用 multi 选项。

上述方法接受以下参数:

  • 过滤文档以确定要更新哪些文档。这些过滤器与查询操作中使用的过滤器具有相同的语法规则。
    •   查询过滤文档,使用表达式:指定相等条件,查找字段值为:
的所有文档

        { : , ... }

    •   查询过滤文档,可以使用查询运算符指定条件:

        { : { : }, ... }

  • 指定更新内容的更新文档;或者替换匹配文档并保持 _id 字段不变的替换文档。
  • 一份选项文件。

1.2 行为

原子性

MongoDB 中的写入操作在单文档级别是原子的。

_id 字段

文档一旦创建,_id字段值就是固定的,无法更新,也不能用_id字段值与原始文档不同的文档替换原始文档。

文档尺寸

当执行的更新操作导致文档增长到大于其分配的大小时,更新操作会重新定位磁盘上的文件。

现场订购

MongoDB 会维护字段写入的顺序,除非遇到以下情况:

  • _id 字段始终位于第一个。
  • 更新期间重命名一个或部分字段可能会导致字段顺序发生变化

2.6版本的变化:从2.6版本开始,MongoDB尽量保持字段写入的顺序,但在之前的版本中并非如此。

向上插入选项

如果 db.collection.update()、db.collection.updateOne()、db.collection.updateMany() 或 db.collection.replaceOne() 包含

"upsert : true" 并且使用指定的过滤器没有匹配到任何文档,则此操作将创建一个新文档并将其插入到数据库中。如果文档匹配,此操作将修改或替换匹配的一个或多个文档。

1.3示例集合

本页的示例使用 mongo shell 中的 db.collection.find() 方法。在mongo shell中,如果游标没有赋值给var类型的变量,游标会自动迭代20次,打印结果集中的前20个文档。

在 mongo shell 中执行以下语句,将数据倒入 users 集合中。

db.users.insertMany(

[

{

_id:1,

名称:“苏”,

年龄:19岁,

类型:1,

状态:“P”,

最爱:{艺术家:“毕加索”,食物:“披萨”},

已完成: [ 17, 3 ],

徽章:[“蓝色”,“黑色”],

分:[

{ 积分: 85, 奖金: 20 },

{ 积分:85,奖金:10 }

]

},

{

_id:2,

姓名:“鲍勃”,

年龄:42岁,

类型:1,

状态:“A”,

最爱:{艺术家:“Miro”,食物:“蛋白酥皮”},

已完成: [ 11, 25 ],

徽章:[“绿色”],

分:[

{ 积分: 85, 奖金: 20 },

{ 积分:64,奖金:12 }

]

},

{

_id:3,

名称:“ahn”,

年龄:22岁,

类型:2,

状态:“A”,

最爱:{艺术家:“卡萨特”,食物:“蛋糕”},

已完成: [ 6 ],

徽章:[“蓝色”,“毕加索”],

分:[

{ 积分: 81, 奖金: 8 },

{ 积分:55,奖金:20 }

]

},

{

_id:4,

姓名:“夕”,

年龄:34岁,

类型:2,

状态:“D”,

最爱:{艺术家:“夏加尔”,食物:“巧克力”},

已完成: [ 5, 11 ],

徽章:[“毕加索”,“黑色”],

分:[

{ 积分: 53, 奖金: 15 },

{ 积分:51,奖金:15 }

]

},

{

_id:5,

名称:“xyz”,

年龄:23​​岁,

类型:2,

状态:“D”,

最爱:{艺术家:“野口”,食物:“牛轧糖”},

已完成: [ 14, 6 ],

徽章:[“橙色”],

分:[

{ 积分:71,奖金:20 }

]

},

{

_id:6,

名称:“abc”,

年龄:43岁,

类型:1,

状态:“A”,

最爱:{食物:“披萨”,艺术家:“毕加索”},

已完成: [ 18, 12 ],

徽章:[“黑色”,“蓝色”],

分:[

{ 积分: 78, 奖金: 8 },

{ 积分:57,奖金:7 }

]

}

]

)

1.4 更新文档的指定字段

为了更改字段,MongoDB提供了更新运算符,例如使用$set来修改字段值。

更新后的文档格式为:

{

: { : , ... },

: { : , ... },

...

}

一些更新操作符如果不存在就会创建要更新的字段,例如$set。

db.collection.updateOne()

3.2版本新增功能

以下示例演示如何使用 db.collection.updateOne() 方法,并且匹配条件 favorites.artist equals "Picasso" 来更新多个匹配文档中的第一个文档:

  • 使用运算符$set将字段m.genealogy-computer-tips.com的值更改为“pie”,并将字段的type值更改为3。
  • 使用运算符$currentDate 将字段lastModified 的值更改为当前时间。如果字段lastModified不存在,$currentDate将创建该字段。

db.users.updateOne(

{ "favorites.artist": "毕加索" },

{

$set: { "m.genealogy-computer-tips.com": "pie", type: 3 },

$当前日期:{lastModified:true}

}

)

db.collection.updateMany()

3.2版本新增功能

以下示例演示如何使用 db.collection.updateMany() 方法,且匹配条件 favorites.artist equals "Picasso" 来更新所有匹配的文档:

  • 使用运算符$set将字段m.genealogy-computer-tips.com的值更改为“pie”,并将字段的type值更改为3。
  • 使用运算符$currentDate 将字段lastModified 的值更改为当前时间。如果字段lastModified不存在,$currentDate将创建该字段。

db.users.updateMany(

{ "favorites.artist": "毕加索" },

{

$set: { "favorites.artist": "Pisanello", type: 3 },

$当前日期:{lastModified:true}

})

Db.collection.update()

以下示例演示如何使用 db.collection.updateOne() 方法,并且匹配条件 favorites.artist equals "Picasso" 来更新多个匹配文档中的第一个文档:

  • 使用运算符$set将字段m.genealogy-computer-tips.com的值更改为“pie”,并将字段的type值更改为0。
  • 使用运算符$currentDate 将字段lastModified 的值更改为当前时间。如果字段lastModified不存在,$currentDate将创建该字段。

db.users.update(

{ "favorites.artist": "Pisanello" },

{

$set: { "m.genealogy-computer-tips.com": "披萨", type: 0, },

$当前日期:{lastModified:true}

})

使用 db.collection.update() 方法和 multi: true 选项更新多个文档

db.users.update(

{ "favorites.artist": "Pisanello" },

{

$set: { "m.genealogy-computer-tips.com": "披萨", type: 0, },

$当前日期:{lastModified:true}

},

{ 多:真 })

1.5 替换文件

要替换文档中除 _id 字段之外的所有内容,请将新文档作为第二个参数传递给 db.collection.replaceOne() 或 db.collection.update()。替换文件必须包含 :

替换文档可以包含与原始文档不同的字段。由于_id字段没有改变,所以替换文档中的_id字段可以省略。如果替换文档包含_id字段,则替换文档的

_id 字段值必须与原始文档相同。

db.collection.replaceOne

下面的示例演示如何使用 db.collection.replaceOne() 方法和 name 等于“abc”的过滤条件,将集合 users 中第一个匹配的文档替换为新文档。

db.users.replaceOne(

{ 名称: "abc" },

{ 姓名:“amy”,年龄:34,类型:2,状态:“P”,收藏夹:{“艺术家”:“大理”,食物:“甜甜圈” } })

db.collection.update

下面的示例演示如何使用 db.collection.update() 方法和 name 等于“xyz”的过滤条件,将集合 users 中第一个匹配的文档替换为新文档。

db.users.update(

{ 名称: "xyz" },

{姓名:“mee”,年龄:25,类型:1,状态:“A”,收藏夹:{“艺术家”:“马蒂斯”,食物:“芒果”} })

其他方法

以下列出了删除文档的其他方法:

  • db.collection.findOneAndReplace().
  • db.collection.findOneAndUpdate().
  • db.collection.findAndModify().
  • m.genealogy-computer-tips.com().
  • db.collection.bulkWrite().

写入确认

对于写入确认,您可以指定写入操作所需的确认级别。详情请参阅写关注

2 删除文档

2.1 删除方法

MongoDB提供了以下方法来删除集合中的文档。

db.collection.remove()

删除与指定过滤器匹配的一个或所有文档

db.collection.deleteOne()

最多删除一个文档,即使使用指定的过滤器匹配多个文档也是如此。

3.2版本新增功能

db.collection.deleteMany()

删除所有匹配的文档。

3.2版本新增功能

您可以使用条件和过滤器来识别要删除的文档。这些过滤器与用于读取操作的过滤器具有相同的语法规则。

  • 查询过滤文档使用:指定相等条件,过滤掉字段值为:
的所有文档

    { : , ... }

  • 查询过滤文档可以使用查询运算符指定匹配条件:

    { : { : }, ... }

2.2 删除行为

索引

执行删除操作时,即使删除集合中的所有文档,索引也不会被删除。

原子性

MongoDB 中的所有写入操作在单文档级别都是原子的。

2.3示例集合

本页面提供了在 mongo shell 中使用删除操作的示例。在 mongo shell 中执行以下语句将数据倒入 users 集合中。

注:

如果要插入的文档的_id字段值与集合中现有文档的_id字段值相同,则在插入数据之前必须删除集合(db.users.drop())。

db.users.insertMany(

[

{

_id:1,

名称:“苏”,

年龄:19岁,

类型:1,

状态:“P”,

最爱:{艺术家:“毕加索”,食物:“披萨”},

已完成: [ 17, 3 ],

徽章:[“蓝色”,“黑色”],

分:[

{ 积分: 85, 奖金: 20 },

{ 积分:85,奖金:10 }

]

},

{

_id:2,

姓名:“鲍勃”,

年龄:42岁,

类型:1,

状态:“A”,

最爱:{艺术家:“Miro”,食物:“蛋白酥皮”},

已完成: [ 11, 25 ],

徽章:[“绿色”],

分:[

{ 积分: 85, 奖金: 20 },

{ 积分:64,奖金:12 }

]

},

{

_id:3,

名称:“ahn”,

年龄:22岁,

类型:2,

状态:“A”,

最爱:{艺术家:“卡萨特”,食物:“蛋糕”},

已完成: [ 6 ],

徽章:[“蓝色”,“红色”],

分:[

{ 积分: 81, 奖金: 8 },

{ 积分:55,奖金:20 }

]

},

{

_id:4,

姓名:“夕”,

年龄:34岁,

类型:2,

状态:“D”,

最爱:{艺术家:“夏加尔”,食物:“巧克力”},

已完成: [ 5, 11 ],

徽章:[“红色”,“黑色”],

分:[

{ 积分: 53, 奖金: 15 },

{ 积分:51,奖金:15 }

]

},

{

_id:5,

名称:“xyz”,

年龄:23​​岁,

类型:2,

状态:“D”,

最爱:{艺术家:“野口”,食物:“牛轧糖”},

已完成: [ 14, 6 ],

徽章:[“橙色”],

分:[

{ 积分:71,奖金:20 }

]

},

{

_id:6,

名称:“abc”,

年龄:43岁,

类型:1,

状态:“A”,

最爱:{食物:“披萨”,艺术家:“毕加索”},

已完成: [ 18, 12 ],

徽章:[“黑色”,“蓝色”],

分:[

{ 积分: 78, 奖金: 8 },

{ 积分:57,奖金:7 }

]

}

])

2.4删除所有文档

要删除所有文档,请使用 db.collection.deleteMany() 或 db.collection.remove() 方法并将空过滤器文档 {} 传递给该方法。

db.collection.deleteMany()

例如,使用 db.collection.deleteMany() 方法删除 users 集合中的所有文档:

db.users.deleteMany({})

返回的结果文档包含操作状态:

{“已确认”:true,“已删除计数”:7}

db.collection.remove()

或者使用 db.collection.remove() 方法删除所有文档:

db.users.remove({})

要删除集合中的所有文档,db.collection.drop()方法可能会更高效;使用 db.collection.drop() 方法删除集合中的所有文档及其索引,然后重新创建集合和索引。

3.5删除所有匹配的文档

要删除所有匹配的文档,请将过滤器传递给 db.collection.deleteMany() 或 db.collection.remove() 方法。

db.collection.deleteMany()

例如使用db.collection.deleteMany()方法删除users集合中status字段值为“A”的文档

db.users.deleteMany({ status : "A" })

返回结果:

{“已确认”:true,“已删除计数”:3}

db.collection.remove()

或者使用 db.collection.remove() 方法删除 users 集合中 status 字段值为“P”的文档

db.users.remove( { status : "P" } )

对于大型删除操作,首先将要保留的文档复制到新的集合中,然后使用 db.collection.drop() 删除原始集合。这种方法可能更有效。

2.6 仅删除一个匹配的文档

即使匹配到多个文档,也只删除其中一个,使用db.collection.deleteOne()方法,或者使用db.collection.remove()方法并使用参数并设置为true或 1 。

db.collection.deleteOne()

例如使用 db.collection.deleteOne() 删除集合中状态字段值为“D”的第一个文档:

db.users.deleteOne( { status: "D" } )

db.collection.remove()

或者使用 db.collection.remove() 方法删除 users 集合中第一个状态字段值为“D”的文档:

db.users.remove( { status: "D" }, 1)

其他方法:

  • db.collection.findOneAndDelete():该方法提供排序选项,可以删除按指定顺序排序的第一个文档。
  • db.collection.findOneAndModify():该方法提供排序选项,可以删除按指定顺序排序的第一个文档。
  • db.collection.bulkWrite()

2.7 写入确认

对于写入确认,您可以指定写入操作所需的确认级别。详情请参阅写关注

3 批量写入操作

3.1 概述

MongoDB客户端具有执行批量写入的能力。批量写入操作仅影响一个集合。 MongoDB 将其留给应用程序来确定批量写入操作可接受的安全级别。

3.2版本新增:

db.collection.bulkWrite()方法提供批量插入、更新和删除。批量插入也可以使用 db.collection.insertMany() 方法完成。

3.2排序和非排序操作

可以批量写入一批已排序或未排序的文档。

对于有序的操作列表,MongoDB 按顺序执行操作。如果执行写入操作时发生错误,MongoDB 将返回,而不处理列表中的其余操作。

对于无序列表的操作,MongoDB 并行执行操作,但不保证这种行为。如果执行写操作时发生错误,MongoDB将继续执行列表中剩余的操作。

MongoDB 处理有序列表比无序列表慢,因为处理有序列表时,每个操作都必须等待前一个操作完成。

bulkWrite() 方法默认按顺序执行操作。在选项文档中设置ordered: false 以无序方式执行。

3.3 bulkWrite()

bulkWrite() 支持以下写入操作:

  • 插入一个
  • 更新一
  • 更新很多
  • 替换一个
  • 删除一个
  • 删除很多

每个写入操作都会作为数组中的文档传递给bulkWrite()。

例如,以下执行多个写入操作:

合集人物包含以下文档:

{ "_id" : 1, "char" : "布里斯班", "class" : "僧侣", "lvl" : 4 },

{ "_id" : 2, "char" : "埃尔登", "class" : "炼金术士", "lvl" : 3 },

{ "_id" : 3, "char" : "Meldane", "class" : "游侠", "lvl" : 3 }

以下bulkWrite()方法执行多个操作:

尝试{

db.characters.bulkWrite(

[

{ insertOne :

{

“文档”:

{

"_id" : 4, "char" : "迪特拉斯", "class" : "野蛮人", "lvl" : 4

}

}

},

{ insertOne :

{

“文档”:

{

“_id”:5,“char”:“Taeln”,“class”:“战斗机”,“lvl”:3

}

}

},

{ 更新一:

{

"filter" : { "char" : "Eldon" },

"更新" : { $set : { "状态" : "严重伤害" } }

}

},

{删除一个:

{ "filter" : { "char" : "布里斯班"} }

},

{ 替换一个:

{

"filter" : { "char" : "Meldane" },

“替换”:{“char”:“Tanys”,“class”:“oracle”,“lvl”:4}

}

}

]

);}抓住 (e) {

打印(e);}

运算返回结果:

{

“已确认”:正确,

“已删除计数”:1,

"插入数量": 2,

“匹配计数”:2,

"更新插入计数": 0,

“插入的Id”:{

“0”:4,

“1”:5

},

“upsertedIds”:{

}}

3.4文档批量插入分片集策略

批量插入操作,包括初始数据插入和定期数据导入,会影响分片集群的性能。对于大型插入操作,请考虑以下策略:

预分割集合(预分割集合)

如果分片集合为空,则该集合只有一个初始块,并且该块驻留在一个分片中。然后,MongoDB 必须花时间接收数据、创建分片,并将多个块分布到可用分片上。为了避免性能下降,您可以提前对集合进行分片。

乱写

为了提高写入分片集群的性能,请将bulkWrite()方法的ordered选项参数设置为false。 mongos 会尝试同时写入多个片段。

避免单调调整

如果在分片键单调递增时插入文档,则所有插入的数据将运行到集合的最后一个块,这总是发生在一个分片上。因此簇的插入容量永远不能超过切片的插入容量。

如果插入量大于切片可以处理的最大量,并且无法避免分片键随着插入操作而增长,那么请考虑按​​照以下策略修改您的应用程序:

  • 修改分片键的二进制位数,这样可以保留信息并避免插入顺序与递增值的序列相关联。
  • 交换第一个和最后一个 16 位字以调整插入。

例如,以下 C++ 代码交换 BSON ObjectId 的第一个和最后一个 16 位字,以便它们不再单调增加。

使用名称空间 mongo;

OID make_an_id() {

OID x = OID::gen();

const unsigned char *p = x.getData();

交换( (无符号短&) p[0], (无符号短&) p[10] );

返回x;

}

void foo() {

//创建对象

BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "姓名" << "简" );

//现在我们可以将o插入到分片集合中

}

4 SQL与MongoDB映射图

4.1术语和概念

下表为SQL与MongoDB

的术语及概念对应关系

SQL 术语/概念

MongoDB 术语/概念

数据库

数据库

桌子

收藏

文档或BSON文档(文档或BSON文档)

索引(索引)

索引

表连接

嵌入文档和链接

主键

指定一个或多个唯一列作为主键

主键

在 MongoDB 中,主键自动设置为 _id 字段。

聚合(聚合操作)(如group by)

聚合管道

4.2可执行程序

下表列出了当前数据库可执行程序与MongoDB可执行程序的对比。

此列表并不详尽。

MongoDB

MySQL

甲骨文

Informix

DB2

数据库服务器

mongod

mysqld

甲骨文

IDS

DB2 服务器

数据库客户端

蒙戈

mysql

sqlplus

数据库访问

DB2 客户端

4.3示例

SQL语句与MongoDB语句的对应关系如下。假设以下条件:

SQL语句中的表名为users。

MongoDB 中的集合称为用户,包含以下文档模型:

{

_id:ObjectId("509a8fb2f3f4948bd2f983a0"),

user_id: "abc123",

年龄:55岁,

状态:'A'

}

创建和更改

表级操作对应关系如下所示。

SQL 模式语句

MongoDB 架构声明

创建表用户(

id MEDIUMINT 不为空

自动增量,

user_id Varchar(30),

年龄号码,

状态字符(1),

主键(id)

)

第一次执行insert()操作时,将隐式创建一个集合。

如果不指定_id字段,则自动添加主键_id。

db.users.insert(

{ user_id: "abc123", 年龄: 55, 状态: "A" }

)

还可以显示创建收藏:

db.createCollection("用户")

更改表用户

添加 join_date DATETIME

集合不描述和强制文档的结构;在集合级别,文档结构 没有更改

但在文档级别,可以使用 update() 操作和 $set 运算符向现有文档添加字段。

db.users.update(

{ },

{ $set: { join_date: new Date() } },

{ 多:真 }

)

更改表用户

删除列 join_date

集合不描述和强制文档的结构;在集合级别,文档结构 没有更改

但是在文档级别,可以使用 update() 操作和 $unset 运算符来删除文档中的字段。

db.users.update(

{ },

{ $unset: { join_date: "" } }, { multi: true }

)

创建索引 idx_user_id_asc

ON 用户(user_id)

db.users.createIndex( { user_id: 1 } )

创建索引

idx_user_id_asc_age_desc

ON 用户(user_id,年龄 DESC)

db.users.createIndex( { user_id: 1, 年龄: -1 } )

删除表用户

db.users.drop()

插入

插入操作的对应关系如下表

SQL插入语句

MongoDB insert() 语句

插入用户(user_id、年龄、状态)

值(“bcd001”,45,“A”)

db.users.insert( { user_id: "bcd001", 年龄: 45, 状态: "A" })

询价

查询操作的对应关系如下表

注:

find()方法的执行结果始终包含返回文档中的_id字段,除非通过投影排除该字段。考虑到这一点,即使相应的 find() 方法中不包含 _id 字段,以下 SQL 语句也可能包含 _id 字段。

SQL查询语句

MongoDB find() 语句

从用户中选择*

db.users.find()

选择 ID,

user_id,

状态

来自用户

db.users.find( { }, { user_id: 1, 状态: 1 })

SELECT user_id, statusFROM users

db.users.find( { }, { user_id: 1, status: 1, _id: 0 })

从用户中选择*WHERE状态=“A”

db.users.find( { status: "A" })

SELECT user_id, statusFROM usersWHERE status = "A"

db.users.find(    { status: "A" },    { user_id: 1, status: 1, _id: 0 })

SELECT *FROM usersWHERE status != "A"

db.users.find(    { status: { $ne: "A" } })

从用户中选择*,其中状态=“A”并且年龄= 50

db.users.find(    { 状态: "A",      年龄: 50 })

从用户中选择*WHERE状态=“A”或年龄=50

db.users.find(    { $or: [ { 状态: "A" } ,             { 年龄: 50 } ] })

从年龄> 25的用户中选择*

db.users.find(    { 年龄: { $gt: 25 } })

从年龄 < 25 岁的用户中选择 *

db.users.find(   { 年龄: { $lt: 25 } })

从年龄 > 25 且年龄 <= 50 的用户中选择 *

db.users.find(   { 年龄: { $gt: 25, $lte: 50 } })

SELECT *FROM usersWHERE user_id like "%bc%"

db.users.find( { user_id: /bc/ } )

SELECT *FROM usersWHERE user_id like "bc%"

db.users.find( { user_id: /^bc/ } )

SELECT *FROM usersWHERE status = "A"ORDER BY user_id ASC

db.users.find( { status: "A" } ).sort( { user_id: 1 } )

SELECT *FROM usersWHERE status = "A"ORDER BY user_id DESC

db.users.find( { status: "A" } ).sort( { user_id: -1 } )

从用户中选择 COUNT(*) 个

db.users.count()

db.users.find().count()

从用户中选择 COUNT(user_id)

db.users.count( { user_id: { $exists: true } } )

db.users.find( { user_id: { $exists: true } } ).count()

从年龄 > 30 的用户中选择 COUNT(*) 个

db.users.count( { 年龄: { $gt: 30 } } )

db.users.find( { 年龄: { $gt: 30 } } ).count()

从用户中选择不同的(状态)

db.users.distinct(“状态”)

选择 *FROM usersLIMIT 1

db.users.findOne()

db.users.find().limit(1)

从用户中选择*LIMIT 5SKIP 10

db.users.find().limit(5).skip(10)

解释 SELECT *FROM usersWHERE status = "A"

db.users.find( { status: "A" } ).explain()

更新记录

以下展示了更新操作的对应关系

SQL更新语句

MongoDB update() 语句

更新用户设置状态=“C”,其中年龄> 25

db.users.update(

{ 年龄: { $gt: 25 } }, { $set: { 状态: "C" } }, { 多: true }

)

更新用户SET年龄=年龄+3WHERE状态=“A”

db.users.update(

{ 状态: "A" } , { $inc: { 年龄: 3 } }, { 多: true }

)

删除记录

更新和删除操作的对应关系如下表

SQL更新语句

MongoDB update() 语句

从用户中删除,其中状态=“D”

db.users.remove( { status: "D" } )

删除用户

db.users.remove({})

5 阅读关注

3.2版本新增功能

MongoDB 3.2 引入了副本集和副本集分片的 readConcern 查询选项。默认情况下,执行查询时,MongoDB 使用“本地”读取关注来返回 MongoDB 实例上可用的最新数据。即使数据尚未保存在副本集主成员中并且可能已回滚。

存储引擎和驱动程序支持

对于WiredTiger存储引擎,readConcern选项允许客户端选择读隔离级别。您可以指定“多数”读关注来读取已写入副本集主成员的数据,并且该数据无法回滚。

对于MMAPv1存储引擎,只能将readConcern指定为“local”。

小贴士:

serverStatus 命令返回字段 storageEngine.supportsComfilledReads 以指示存储引擎是否支持“多数”读关注。

阅读注意力水平

默认情况下,MongoDB readConcern 配置为“local”,这并不能保证读取的数据不会回滚。

如果指定readConcern为“majority”来读取已写入副本集Primary成员的数据,则该数据不会回滚。

等级

描述

“本地”

默认级别。查询返回MongoDB实例中的最新数据。不保证数据会写入副本集主要成员。

“大多数”

查询操作返回写入MongoDB实例中副本集Primary成员的最新数据副本。

为了使用“majority”级别的读关注,您必须使用WiredTiger存储引擎并使用enableMajorityReadConcern命令行选项(或使用replication.enableMajorityReadConcern设置配置文件)。

只有使用副本集选举协议版本1的副本集支持“多数”。使用协议版本 0 的副本集不支持“多数”。

为了让线程读取其已写入的数据,请在副本集主要成员上使用“多数”级别的读关注和“多数”级别的写关注。

除了读关注度外,节点上的最新数据不一定是系统中的最新数据。

阅读关注选项

使用 readConcern 选项指定读取关注级别:

阅读关注:{ 级别:<"majority"|"local"> }

对于级别字段,将值指定为“majority”或“local”。

readConcern 选项也可用于以下操作:

  • 查找命令
  • aggregate 命令和 db.collection.aggregate() 方法
  • 独特的命令
  • 计数命令
  • 并行CollectionScan命令
  • geoNear 命令
  • geoSearch 命令

要在 mongo shell 中为 db.collection.find() 方法指定读取关注点,请使用cursor.readConcern() 方法。

6 写一个关注

写入关注点描述了 MongoDB 对在独立 mongod 或副本集或分片集群上执行的写入操作的确认级别。对于分片集群,mongos 实例会将写注意力传递给每个分片。

3.2版本的变化是:对于使用protocolVersion:1的副本集并启用journal。

  • w:“多数”表示 j:true。
  • 即使设置了j选项写入Primary成员,Secondary成员在数据写入各自的磁盘后仍然会确认复制写入操作。

2.6版本的变化:新协议提高了写操作的写注意力,并且不再需要调用getLastError。以前的版本需要在写入操作后立即调用 getLastError 才能指定写入关注点。

书写说​​明

写入文件包含以下字段:

{ w: , j: , w超时: }

  • w 选项请求确认写入操作已传播到具有指定序列号的 mongod 实例或具有指定标签的 mongod 实例。
  • j 选项请求确认写入操作已写入日志。
  • wtimeout 指定一个时间限制,以防止写操作无限期地阻塞进程。

w 选项

w 选项请求确认写入操作已传播到具有指定序列号的 mongod 实例或具有指定标签的 mongod 实例。

使用w选项,w:可用。

注:

除非j:true,独立的mongod实例和副本集主成员在内存中应用写操作后将设置写操作确认。

3.2:版本变化:对于使用protocolVersion:1的副本集,无论j选项如何配置,数据写入Secondary成员各自的磁盘后,Secondary成员确认复制写入操作。

价值

描述

请求确认写入操作已传播到具有指定序列号的 mongod 实例。例如:

w:1

请求确认写入操作已传播到独立的mongod或副本集主成员。 w: 1 是 MongoDB 的默认值。

w:0

不请求确认写入操作。但是,如果设置为w:0,则返回的信息可能包括应用程序中的套接字异常和网络错误。

如果指定 w: 0 但 j: true,则 j: true 确保来自独立 mongod 或副本集主成员的确认请求。

将number设置为大于1仅对来自副本集指定成员(包括主成员)的确认请求有效。

“大多数”

3.2版本新增功能

写入确认请求传播到大多数选定的节点(包括主成员),并已写入其各自的磁盘日志。

对于副本集,使用protocolVersion:1,w:“majority”表示j:true。因此,与 w: 不同,使用 w: "majority" 主副本集也会在写入确认之前写入磁盘日志。

写确认设置为w:“majority”的写操作返回给客户端后,客户端将读取结果,并将读关注设置为“majority”。

写入操作确认请求已传播到指定标签的副本集成员。

J 选项请求确认写入操作已记录。

j

请求确认 mongod 实例已将写操作记录到日志中,指定 w: 。 j: true 单独并不能保证写操作不会因为副本集主成员的故障转移而回滚。

3.2版本的变化:设置j:true,MongoDB只有在请求成员将写操作记录到日志后才返回结果。在副本集中写入注意力。在之前的版本中,j: true 请求副本集的主成员写入日志,无论 w: 如何设置。

对于使用protocolVersion:1的副本集,w:“majority”表示j:true。默认情况下启用日志记录。

2.6 版本中的更改,对于运行 --nojournal 选项的 mongod 或 mongos,为写入注意指定 j: true 会产生错误。以前的版本忽略了 j: true。

无超时

对于写入问题,该选项指定以毫秒为单位的时间限制,wtimeout 是唯一将 w 值设置为大于 1 的选项。

如果超过指定的时间限制,wtimeout 将导致写操作返回错误,即使请求的写注意最终会成功。当写操作返回时,MongoDB不会取消对成功数据的修改,直到写关注超过wtimeout时限。

如果不为写注意指定 wtimeout 选项,则无法实现指定的写注意级别,并且写操作将无限期阻塞。将 wtimeout 指定为 0 相当于在不使用 wtimeout 选项的情况下编写关注点。

------------------------------------------------------------ --- ----------------------------------------------------------

转载、引用时请注明出处。

时间短,水平有限。如果有什么不妥的地方,还请指正。

-->