公告推出 MongoDB 8.0,史上最快的 MongoDB!阅读更多 >>推出 MongoDB 8.0,史上最快的 MongoDB!>>

MongoDB CRUD 操作

目录


CRUD 操作的基本定义

用户与数字平台(如网站或网络应用)进行的大多数事务交互包括对四种基本操作的请求

  • 创建新事物(例如,客户档案)。
  • 读取(例如,获取用户的订单详情)。
  • 更新信息(例如,用户的手机号码或电子邮件地址)。
  • 删除(例如,工作电话号码)。

CRUD 是面向数据的,并且根据 HTTP 动词进行了标准化。应用程序的前端捕获信息并将其作为 HTTP 请求发送到中间件,中间件调用适当的数据库函数以完成任务。这四个基本功能统称为 CRUD,即 create(创建)、read(读取)、update(更新)和 delete(删除)的首字母缩写。

HTTP and corresponding database CRUD operations

基本操作的示例

CRUD 方法是您管理数据库数据的主要方式。无论是批量操作还是单个操作,CRUD 操作对每个应用程序都是必不可少的。

创建操作的示例包括在数据库中创建新的用户档案、为用户创建购物车以及创建新的图书目录(批量插入)。

读取操作的示例包括根据用户特定的搜索标准获取产品详情,例如当用户搜索品牌为“apple”的手机时;显示所有 iPhone 模型;显示用户的产品购物车信息;以及查看门户上的员工详细信息。

更新操作的示例包括更新用户的个人信息、购物车信息、账单地址、时间戳或特定范围产品的序列号(批量更新)。

删除操作的示例包括从用户的购物车中删除产品、从收藏中删除书籍以及删除所有超过一定时间周期的记录(批量删除)。

让我们进一步探讨 CRUD 的定义,并检查如何使用 MongoDB 查询语言(MQL)执行 MongoDB CRUD 操作。

MongoDB 中的 CRUD 是什么?

CRUD 操作描述了用户界面约定,允许用户查看、搜索和修改数据库的各个部分。MongoDB 通过其 驱动程序 提供了一种优雅的方式来执行 CRUD 操作,您可以使用您选择的编程语言。

MongoDB 文档通过连接到服务器、查询适当的文档,然后在发送数据回数据库以更新之前更改设置属性来修改。

当涉及到单个 CRUD 操作时

  • 创建操作用于在 MongoDB 数据库中插入新文档。
  • 读取操作用于查询数据库中的文档。
  • 更新操作用于修改数据库中现有的文档。
  • 删除操作用于从数据库中删除文档。

如何执行 CRUD 操作

现在我们已经定义了MongoDB CRUD操作,我们可以看看如何执行单个操作以及如何在MongoDB数据库中操作文档。让我们逐一了解创建、读取、更新和删除文档的过程。

MongoDB methods for CRUD operations

创建操作

对于MongoDB CRUD,如果指定的集合不存在,则执行创建操作时将创建该集合。MongoDB中的创建操作针对单个集合,而不是多个集合。MongoDB中的插入操作在单个文档级别是原子的

MongoDB提供了两种不同的创建操作,可以将文档插入到集合中

insertOne()

如名称所示,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()

通过在所选集合上调用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()方法。仅执行不带参数的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()

要获取满足搜索条件的一个文档,我们可以在选择的集合上简单使用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()

我们可以通过使用选择的集合上的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()

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()方法在指定的集合中替换单个文档。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()

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()

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 }

关系型数据库与非关系型数据库中的 CRUD 性能

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应用?

CRUD应用依赖于CRUD操作进行所有事务和操作。它包括用户界面(前端)、控制器或API,以及处理CRUD操作的数据库。

什么是CRUD操作?

CRUD操作是每个应用程序需要执行以与网络用户交换数据的基本功能——例如,创建新的用户资料(创建)、从数据库中检索产品详情(读取)、在员工门户中更新员工信息(更新),以及从目录中删除特定产品(删除)。

什么是CRUD?

CRUD是一个缩写,用于表示每个应用程序都必须能够执行的基本操作集。它代表创建、读取、更新和删除。

准备好开始了吗?

启动新的集群或无缝迁移到MongoDB Atlas。