目录
用户与数字平台(如网站或网络应用)进行的大多数事务交互包括对四种基本操作的请求
CRUD 是面向数据的,并且根据 HTTP 动词进行了标准化。应用程序的前端捕获信息并将其作为 HTTP 请求发送到中间件,中间件调用适当的数据库函数以完成任务。这四个基本功能统称为 CRUD,即 create(创建)、read(读取)、update(更新)和 delete(删除)的首字母缩写。
CRUD 方法是您管理数据库数据的主要方式。无论是批量操作还是单个操作,CRUD 操作对每个应用程序都是必不可少的。
创建操作的示例包括在数据库中创建新的用户档案、为用户创建购物车以及创建新的图书目录(批量插入)。
读取操作的示例包括根据用户特定的搜索标准获取产品详情,例如当用户搜索品牌为“apple”的手机时;显示所有 iPhone 模型;显示用户的产品购物车信息;以及查看门户上的员工详细信息。
更新操作的示例包括更新用户的个人信息、购物车信息、账单地址、时间戳或特定范围产品的序列号(批量更新)。
删除操作的示例包括从用户的购物车中删除产品、从收藏中删除书籍以及删除所有超过一定时间周期的记录(批量删除)。
让我们进一步探讨 CRUD 的定义,并检查如何使用 MongoDB 查询语言(MQL)执行 MongoDB CRUD 操作。
CRUD 操作描述了用户界面约定,允许用户查看、搜索和修改数据库的各个部分。MongoDB 通过其 驱动程序 提供了一种优雅的方式来执行 CRUD 操作,您可以使用您选择的编程语言。
MongoDB 文档通过连接到服务器、查询适当的文档,然后在发送数据回数据库以更新之前更改设置属性来修改。
当涉及到单个 CRUD 操作时
现在我们已经定义了MongoDB CRUD操作,我们可以看看如何执行单个操作以及如何在MongoDB数据库中操作文档。让我们逐一了解创建、读取、更新和删除文档的过程。
如名称所示,insertOne()允许您将单个文档插入到集合中。在这个例子中,我们将使用一个名为RecordsDB的集合。我们可以通过在RecordsDB上调用insertOne()方法将单个条目插入到我们的集合中。然后,我们以键值对的形式提供要插入的信息,从而建立模式。
db.RecordsDB.insertOne({
name: "Marsh",
age: "6 years",
species: "Dog",
ownerAddress: "380 W. Fir Ave",
chipped: true
})
如果创建操作成功,将创建一个新的文档。该函数将返回一个对象,其中“acknowledged”为“true”,“insertID”为新创建的“ObjectId”。
> db.RecordsDB.insertOne({
... name: "Marsh",
... age: "6 years",
... species: "Dog",
... ownerAddress: "380 W. Fir Ave",
... chipped: true
... })
{
"acknowledged" : true,
"insertedId" : ObjectId("5fd989674e6b9ceb8665c57d")
}
通过在所选集合上调用insertMany()方法,可以一次插入多个项目。在这种情况下,我们将多个项目传递到我们选择的集合(RecordsDB)中,并用逗号分隔。在括号内,我们使用方括号来表示我们正在传递一个多个条目的列表。这通常被称为嵌套方法。
db.RecordsDB.insertMany([{
name: "Marsh",
age: "6 years",
species: "Dog",
ownerAddress: "380 W. Fir Ave",
chipped: true},
{name: "Kitana",
age: "4 years",
species: "Cat",
ownerAddress: "521 E. Cortland",
chipped: true}])
db.RecordsDB.insertMany([{ name: "Marsh", age: "6 years", species: "Dog",
ownerAddress: "380 W. Fir Ave", chipped: true}, {name: "Kitana", age: "4 years",
species: "Cat", ownerAddress: "521 E. Cortland", chipped: true}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5fd98ea9ce6e8850d88270b4"),
ObjectId("5fd98ea9ce6e8850d88270b5")
]
}
读取操作允许您提供特殊的查询过滤器和标准,以便您可以指定您想要哪些文档。MongoDB文档中包含了更多关于可用查询过滤器的信息。也可以使用查询修饰符来更改返回的结果数量。
MongoDB有两种从集合中读取文档的方法
要获取集合中的所有文档,我们可以在所选集合上简单地使用find()方法。仅执行不带参数的find()方法将返回集合中当前的所有记录。
db.RecordsDB.find()
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "6 years", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd993f3ce6e8850d88270b8"), "name" : "Loo", "age" : "3 years", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd994efce6e8850d88270ba"), "name" : "Kevin", "age" : "8 years", "species" : "Dog", "ownerAddress" : "900 W. Wood Way", "chipped" : true }
在结果中,我们可以看到集合中现有的所有记录。请注意,每个记录都有一个分配给“_id”键的“ObjectId”。
如果您想要更具体地执行读取操作并找到所需的记录子集,您可以使用之前提到的过滤标准来选择应返回哪些结果。过滤结果的最常见方式之一是按值搜索。
db.RecordsDB.find({"species":"Cat"})
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
要获取满足搜索条件的一个文档,我们可以在选择的集合上简单使用findOne()方法。如果多个文档满足查询条件,则此方法返回第一个文档,根据自然顺序返回,这反映了磁盘上文档的顺序。如果没有文档满足搜索条件,则函数返回null。该函数的语法形式如下。
db.{collection}.findOne({query}, {projection})
让我们以以下集合为例,比如RecordsDB。
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "8 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "6 years", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd993f3ce6e8850d88270b8"), "name" : "Loo", "age" : "3 years", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd994efce6e8850d88270ba"), "name" : "Kevin", "age" : "8 years", "species" : "Dog", "ownerAddress" : "900 W. Wood Way", "chipped" : true }
然后,我们运行以下代码
db.RecordsDB.find({"age":"8 years"})
我们会得到以下结果
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "8 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
请注意,即使有两个文档满足搜索条件,也只会返回第一个匹配搜索条件的文档。
与创建操作一样,更新操作在单个集合上操作,并在单个文档级别上是原子的。更新操作使用过滤器来选择要更新的文档。
更新文档时应该小心,因为更新是永久的,无法回滚。这也适用于删除操作。
对于MongoDB CRUD,有三种不同的更新文档方法
我们可以通过使用选择的集合上的updateOne()方法来更新当前存在的记录并更改单个文档。为此,我们向方法提供两个参数:一个更新过滤器和更新操作。
更新过滤器定义了我们要更新的项目,更新操作定义了如何更新这些项目。我们首先传递更新过滤器。然后,我们使用“$set”键并提供要更新的字段作为值。此方法将更新第一个匹配提供的过滤器的记录。
db.RecordsDB.updateOne({name: "Marsh"}, {$set:{ownerAddress: "451 W. Coffee St. A204"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "6 years", "species" : "Dog", "ownerAddress" : "451 W. Coffee St. A204", "chipped" : true }
updateMany()允许我们通过传递一个项目列表来更新多个项目,就像我们在插入多个项目时所做的那样。此更新操作使用与更新单个文档相同的语法。
db.RecordsDB.updateMany({species:"Dog"}, {$set: {age: "5"}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
> db.RecordsDB.find()
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "5", "species" : "Dog", "ownerAddress" : "451 W. Coffee St. A204", "chipped" : true }
{ "_id" : ObjectId("5fd993f3ce6e8850d88270b8"), "name" : "Loo", "age" : "5", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd994efce6e8850d88270ba"), "name" : "Kevin", "age" : "5", "species" : "Dog", "ownerAddress" : "900 W. Wood Way", "chipped" : true }
replaceOne()方法在指定的集合中替换单个文档。replaceOne()替换整个文档,这意味着在旧文档中不包含在新文档中的字段将会丢失。
db.RecordsDB.replaceOne({name: "Kevin"}, {name: "Maki"})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.RecordsDB.find()
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "5", "species" : "Dog", "ownerAddress" : "451 W. Coffee St. A204", "chipped" : true }
{ "_id" : ObjectId("5fd993f3ce6e8850d88270b8"), "name" : "Loo", "age" : "5", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
{ "_id" : ObjectId("5fd994efce6e8850d88270ba"), "name" : "Maki" }
删除操作与更新和创建操作一样,在单个集合上操作。删除操作对于单个文档也是原子的。您可以为删除操作提供过滤器来指定要从一个集合中删除的文档。过滤器选项依赖于与读取操作相同的语法。
MongoDB有从集合中删除记录的两种不同方法
deleteOne()从MongoDB服务器上的指定集合中删除文档。使用过滤器准则来指定要删除的项目。它删除第一个匹配提供的过滤器的记录。
db.RecordsDB.deleteOne({name:"Maki"})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.RecordsDB.find()
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
{ "_id" : ObjectId("5fd993a2ce6e8850d88270b7"), "name" : "Marsh", "age" : "5", "species" : "Dog", "ownerAddress" : "451 W. Coffee St. A204", "chipped" : true }
{ "_id" : ObjectId("5fd993f3ce6e8850d88270b8"), "name" : "Loo", "age" : "5", "species" : "Dog", "ownerAddress" : "380 W. Fir Ave", "chipped" : true }
deleteMany()是一种用于通过单个删除操作从所需集合中删除多个文档的方法。将列表传递给方法,并使用与deleteOne()中相同的过滤器准则定义单独的项目。
db.RecordsDB.deleteMany({species:"Dog"})
{ "acknowledged" : true, "deletedCount" : 2 }
> db.RecordsDB.find()
{ "_id" : ObjectId("5fd98ea9ce6e8850d88270b5"), "name" : "Kitana", "age" : "4 years", "species" : "Cat", "ownerAddress" : "521 E. Cortland", "chipped" : true }
NoSQL数据库在创建和读取操作方面优化得更好,并提供了更高的可伸缩性。因此,它们非常适合高负载(处理更多的CRUD操作)。它们在存储信息方面也非常灵活。
在一项由ResearchGate进行的详细实验中,该实验研究了不同类型的NoSQL和SQL数据库在CRUD操作中的表现,结果表明,NoSQL数据库在所有CRUD操作中均显著优于SQL数据库,尤其是在操作数量较高时。例如,MongoDB在数据检索(读取操作)方面表现出色,对于10万次读取(查找/选择)操作的平均性能时间为43.5毫秒。MongoDB在提供原子更新(字段级别更新)方面也有优势,这在其他任何文档型数据库中都更为耗时。
本文介绍了CRUD的基本信息,并举例说明了如何在MongoDB中执行CRUD操作。《MongoDB Atlas》(MongoDB Atlas)提供了一个简单的UI来执行CRUD操作。您可以查阅MongoDB手册,了解更多核心的MongoDB CRUD概念,以开发高性能、可扩展的应用程序。
CRUD代表每个应用程序都应能执行的四项基本操作,即创建、读取、更新和删除操作。这意味着应用程序应能够将数据插入数据库、从数据库中读取数据、更新数据库细节以及根据需要从数据库中删除数据。
CRUD应用依赖于CRUD操作进行所有事务和操作。它包括用户界面(前端)、控制器或API,以及处理CRUD操作的数据库。
CRUD操作是每个应用程序需要执行以与网络用户交换数据的基本功能——例如,创建新的用户资料(创建)、从数据库中检索产品详情(读取)、在员工门户中更新员工信息(更新),以及从目录中删除特定产品(删除)。