【原文地址】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 选项。 |
上述方法接受以下参数:
{
{
1.2 行为
原子性
MongoDB 中的写入操作在单文档级别是原子的。
_id 字段
文档一旦创建,_id字段值就是固定的,无法更新,也不能用_id字段值与原始文档不同的文档替换原始文档。
文档尺寸
当执行的更新操作导致文档增长到大于其分配的大小时,更新操作会重新定位磁盘上的文件。
现场订购
MongoDB 会维护字段写入的顺序,除非遇到以下情况:
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" 来更新多个匹配文档中的第一个文档:
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" 来更新所有匹配的文档:
db.users.updateMany(
{ "favorites.artist": "毕加索" },
{
$set: { "favorites.artist": "Pisanello", type: 3 },
$当前日期:{lastModified:true}
})
Db.collection.update()
以下示例演示如何使用 db.collection.updateOne() 方法,并且匹配条件 favorites.artist equals "Picasso" 来更新多个匹配文档中的第一个文档:
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”,收藏夹:{“艺术家”:“马蒂斯”,食物:“芒果”} })
其他方法
以下列出了删除文档的其他方法:
写入确认
对于写入确认,您可以指定写入操作所需的确认级别。详情请参阅写关注
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()方法并使用
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)
其他方法:
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 会尝试同时写入多个片段。
避免单调调整
如果在分片键单调递增时插入文档,则所有插入的数据将运行到集合的最后一个块,这总是发生在一个分片上。因此簇的插入容量永远不能超过切片的插入容量。
如果插入量大于切片可以处理的最大量,并且无法避免分片键随着插入操作而增长,那么请考虑按照以下策略修改您的应用程序:
例如,以下 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 选项也可用于以下操作:
要在 mongo shell 中为 db.collection.find() 方法指定读取关注点,请使用cursor.readConcern() 方法。
6 写一个关注
写入关注点描述了 MongoDB 对在独立 mongod 或副本集或分片集群上执行的写入操作的确认级别。对于分片集群,mongos 实例会将写注意力传递给每个分片。
3.2版本的变化是:对于使用protocolVersion:1的副本集并启用journal。
2.6版本的变化:新协议提高了写操作的写注意力,并且不再需要调用getLastError。以前的版本需要在写入操作后立即调用 getLastError 才能指定写入关注点。
书写说明
写入文件包含以下字段:
{ 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”的写操作返回给客户端后,客户端将读取结果,并将读关注设置为“majority”。 |
|
写入操作确认请求已传播到指定标签的副本集成员。 |
J 选项请求确认写入操作已记录。
j |
请求确认 mongod 实例已将写操作记录到日志中,指定 w: 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 选项的情况下编写关注点。
------------------------------------------------------------ --- ----------------------------------------------------------
转载、引用时请注明出处。
时间短,水平有限。如果有什么不妥的地方,还请指正。
-->