作者:幻好​


概述

MongoDB 是一种持久化的面向文档的数据库,用于以文档的形式存储和处理数据。

与其他的数据库管理系统一样,MongoDB 可以通过四种基本类型的数据操作来管理数据并与数据交互:

  • C​:创建操作,涉及将数据写入数据库
  • R​:读取操作,查询数据库以从中检索数据
  • U​:更新操作,更改数据库中已存在的数据
  • D​:删除操作,从数据库中永久删除数据

以上四种操作统称为 CRUD 操作,本文主要讲解这四种操作的原理和命令等相关知识。

具体操作

更新文档

接下来重点介绍如何通过更改单个文档中的字段值,以及向集合中的每个文档添加新字段来更新现有文档。

与 insertOne() 和 insertMany() 方法类似,MongoDB 提供了可以一次更新单个文档或多个文档的方法。

为允许用户执行此操作,MongoDB 在更新方法中使用与在查找和检索文档的查询过滤器文档机制相同的查询过滤器文档机制。任何可用于检索文档的查询过滤器文档也可用于指定要更新的文档。

updateOne

通过将景点 长城 的名称更改为 Chuangcheng 的全名。为此,请使用更新单个文档的 ​​updateOne()​​ 方法:

db.spots.updateOne(
{ "name": "长城" },
{
$set: { "name": "Chuangcheng" }
}
)

# 输出:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

​updateOne​​​ 方法的第一个参数是具有单个相等条件的查询过滤器文档,如上一步所述。在此示例中,​​{ "name": "长城" }​​ 查找名称键为 长城 值的文档。此处可以使用任何有效的查询过滤器文档。

第二个参数是更新文档,指定在更新期间应该应用哪些更改。更新文档由作为键的更新操作符和作为值的每个操作符的参数组成。在此示例中,使用的更新运算符是 ​​$set​​​。它负责将文档字段设置为新值,并需要一个具有新字段值的 ​​JSON​​​ 对象。在这里, ​​$set: { "name": "Chuangcheng" }​​ 告诉 MongoDB 将字段名称的值设置为 Chuangcheng。

然后检查更新是否有效:

db.spots.find({"country": "中国"}).pretty()

# 输出:
{
"_id" : ObjectId("61b5d7ba3d2fc20a8483df1c"),
"name" : "Chuangcheng",
"city" : "北京",
"country" : "中国",
"gps" : {
"lat" : 106.384,
"lng" : 39.031
}
}
···

updateMany

如果要修改多个文档,可以使用 ​​updateMany()​​ 方法。

以下示例包括一个空的查询过滤器文档,通过包含一个空的查询文档,此操作将匹配集合中的每个文档,并且 updateMany() 方法将影响它们中的每一个。更新文档向每个文档添加一个新的编辑器字段,并为其分配值:

db.spots.updateMany(
{ },
{
$set: { "remark": "desc..." }
}
)

# 输出:
{ "acknowledged" : true, "matchedCount" : 5, "modifiedCount" : 5 }

根据输出可知,成功更新所有文档,然后通过打印检验:

db.spots.find().pretty()

# 输出:
{
"_id" : ObjectId("61b5d4963d2fc20a8483df1a"),
"name" : "东方明珠",
"country" : "中国",
"city" : "上海",
"location" : {
"lat" : 121.537,
"lng" : 31.258
},
"remark" : "desc..."
}
{
"_id" : ObjectId("61b5d7ba3d2fc20a8483df1b"),
"name" : "故宫",
"city" : "北京",
"country" : "中国",
"gps" : {
"lat" : 116.403,
"lng" : 39.924
},
"remark" : "desc..."
}
. . .

所有返回的文档现在都有一个名为 ​​remark​​​ 的新字段设置为 desc...。通过向 ​​$set​​ 更新操作符提供一个不存在的字段名称,更新操作将在所有匹配的文档中创建缺失的字段并正确设置新值。

删除文档

如果数据库中的数据不需要了进行删除,与 Mongo 的更新和插入操作一样,deleteOne() 方法只删除查询过滤器文档匹配的第一个文档,deleteMany() 方法一次删除多个对象。

deleteOne

比如需要删除某个文档:

db.spots.deleteOne(
{ "name": "Chuangcheng" }
)

# 输出:
{ "acknowledged" : true, "deletedCount" : 1 }

通过输出的 ​​deletedCount​​, 已经有一条文档被删除成功,然后打印校验:

> db.spots.find({"country": "中国"}).pretty()

# 输出
{
"_id" : ObjectId("61b5d4963d2fc20a8483df1a"),
"name" : "东方明珠",
"country" : "中国",
"city" : "上海",
"location" : {
"lat" : 121.537,
"lng" : 31.258
},
"remark" : "desc..."
}
{
"_id" : ObjectId("61b5d7ba3d2fc20a8483df1b"),
"name" : "故宫",
"city" : "北京",
"country" : "中国",
"gps" : {
"lat" : 116.403,
"lng" : 39.924
},
"remark" : "desc..."
}

deleteMany

如果需要一次删除多个文档,可以通过 remark 进行批量过滤匹配删除,这个操作将清空集合:

>  db.spots.deleteMany(
{ "remark" : "desc..." }
)

# 输出:
{ "acknowledged" : true, "deletedCount" : 4 }

通过计算其中的文档数量来验证纪念碑集合现在是否为空:

> db.spots.count()

# 输出:
0

由于刚刚从集合中删除了所有文档,因此此命令返回预期输出 0。

总结

MongoDB 提供了一个强大的查询系统,允许根据复杂的标准精确选择感兴趣的文档,后续会继续对于MongoDB的使用技巧进行详细分享。

通过学习本文笔记,能够使我们对mongo的基本CRUD操作,快速入门,当然学习完之后还需自己动手实践。


想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?

​恒生LIGHT云社区​​,由恒生电子搭建的金融科技专业社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。