MongoDB中提供了三种更新集合中的文档的方式,分别是更新一条文档,更新多条文档和替换一条文档的方式,语法如下:
其中,
collection:指的是集合名称;
filter:必填,指的是过滤条件,与查询文档中的Query查询选择器是一样的,使用方式可参考查询文档;
update:必填,指的是更新的方式,也是我们更新文档需要重点关注的地方;
options:可选,指的是其他的选项;
update参数语法:
{
: { : , ... },
: { : , ... },
...
}
我们以更新其中一个字段为例, 更新字段中的值使用的 operator 是 $set
例子:
查询集合中的数据:
{ "_id" : "1001", "name" : "张三", "fruits" : [ "apple", "orange" ] }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
修改_id为1001的人员的姓名为张三2 :
db.test.updateOne(
{ "_id": "1001" },
{ $set: { "name": "张三2" } }
);
执行后查询集合中的数据:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ] }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
执行修改操作后发现编号为1001的人员的姓名已经修改成了张三2。
我们已经了解到了如何修改一条数据,使用到了$set 操作,下面我们对操作字段的操作进行详细了解一下:
语法:{ $set: {
此操作再刚刚更新一条文档的时候已经讲解过了,这里省略。
另外此操作也可以增加新字段并设置Value做为初始值。
语法:{ $currentDate: {
此操作可以设置当前时间作为数据的更新时间,可以将时间更新到已经存在的字段,也可以创建新的字段作为更新时间。
例子:
更新编号为1001的人员的最后修改时间:
db.test.updateOne(
{"_id": "1001"},
{ $currentDate: { lastModified: true }
});
查询所有数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "lastModified" : ISODate("2023-04-06T02:34:49.783Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现增加了最后修改时间的字段。
再次执行更新编号为1001的人员的最后修改时间查询的所有数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "lastModified" : ISODate("2023-04-06T02:36:00.703Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现时间发生了变化。所以此操作可以更新当前时间到字段,如果字段不存在则创建字段
语法:{ $inc: {
此操作可以在原有字段值的基础上进行增减操作。
另外需要注意的是,如果字段不存在,则会新增字段并设置Value做为初始值。
例子:
我们在原有数据的基础上增加一个成绩字段。
db.test.updateOne(
{"_id": "1001"},
{ $set: { score: 100 } }
);
现在我们对成绩进行增加20分的操作:
db.test.updateOne(
{"_id": "1001"},
{ $inc: { score: 20 } }
);
我们查询一下数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "lastModified" : ISODate("2023-04-06T02:36:00.703Z"), "score" : 120 }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现成绩已经变成了120,增加成功了。
下面我们对成绩再进行减少40分的操作:
db.test.updateOne(
{"_id": "1001"},
{ $inc: { score: -40 } }
);
我们查询一下数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "lastModified" : ISODate("2023-04-06T02:36:00.703Z"), "score" : 80 }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现成绩已经变成了80,减少成功了。
扩展:此操作可以用作自增、自减
语法:{ $unset: {
此操作可以移除指定的字段
例子:
下面我们移除成绩字段:
db.test.updateOne(
{"_id": "1001"},
{ $unset: { score: "" } }
);
查询一下数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "lastModified" : ISODate("2023-04-06T02:36:00.703Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现成绩字段已经被移除。
语法:{$rename: {
例子:
下面我们将最后更新时间字段lastModified重命名成updateTime:
db.test.updateOne(
{"_id": "1001"},
{ $rename: { "lastModified": "updateTime" } }
);
查询一下数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "updateTime" : ISODate("2023-04-06T02:36:00.703Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
发现更新时间字段已经重命名成功。
语法:
db.collection.updateOne(
,
{ $setOnInsert: { : , ... } },
{ upsert: true }
)
此操作类似于新增数据后进行初始化操作。
说明:upsert:true 代表如果未找到待更新的数据则执行插入操作。
例子:
更新编号为1004的用户,初始化成绩为100:
db.test.updateOne(
{"_id": "1004"},
{ $set: { "name": "田七" }, $setOnInsert: { score: 100 } },
{ upsert: true}
);
查询数据如下:
{ "_id" : "1001", "name" : "张三2", "fruits" : [ "apple", "orange" ], "updateTime" : ISODate("2023-04-06T02:36:00.703Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
{ "_id" : "1004", "name" : "田七", "score" : 100 }
下面我们以此更新编号为1001的用户:
db.test.updateOne(
{"_id": "1001"},
{ $set: { "name": "田七" }, $setOnInsert: { score: 100 } },
{ upsert: true}
);
查询数据如下:
{ "_id" : "1001", "name" : "田七", "fruits" : [ "apple", "orange" ], "updateTime" : ISODate("2023-04-06T02:36:00.703Z") }
{ "_id" : "1002", "name" : "李四", "fruits" : [ "banana", "apple" ] }
{ "_id" : "1003", "name" : "王五", "fruits" : [ "banana", "apple", "orange" ] }
{ "_id" : "1004", "name" : "田七", "score" : 100 }
发现操作仅对新增数据有效,类似于新增数据后初始化字段,另外$set中的字段也会添加到新增的数据中。
true 代表如果未找到待更新的数据则执行插入操作。
false 代表始终不执行插入操作。
默认值为 false
此选项不再写示例进行介绍,可以参考上面提到的 $setOnInsert 操作