猫鼬101

2025-06-07

猫鼬101

Mongoose 是一个使 MongoDB 更易于使用的库。它做了两件事:

  1. 它为 MongoDB 集合提供结构
  2. 它为您提供有用的方法

在本文中,您将学习如何在基本层面上使用 Mongoose。

先决条件

我假设您已经完成了以下操作:

  1. 您已在计算机上安装了 MongoDB
  2. 您知道如何设置本地 MongoDB 连接
  3. 您知道如何查看数据库中的数据
  4. 你知道 MongoDB 中的“集合”是什么吗

如果您对这些都不了解,请在继续之前阅读“如何设置本地 MongoDB 连接” 。

我还假设您知道如何使用 MongoDB 创建一个简单的 CRUD 应用。如果您不知道如何操作,请在继续阅读之前阅读“如何使用 Node、Express 和 MongoDB 构建 CRUD 应用” 。

连接到数据库

首先,您需要下载 Mongoose。

npm install mongoose --save
Enter fullscreen mode Exit fullscreen mode

你可以使用 方法来连接数据库connect。假设我们要连接一个名为 的数据库street-fighters。以下是你需要的代码:

const mongoose = require("mongoose");
const url = "mongodb://127.0.0.1:27017/street-fighters";

mongoose.connect(url, { useNewUrlParser: true });
Enter fullscreen mode Exit fullscreen mode

我们想知道连接是否成功或失败。这有助于我们进行调试。

要检查连接是否成功,我们可以使用open事件。要检查连接是否失败,我们也可以使用error事件。

const db = mongoose.connection;
db.once("open", _ => {
  console.log("Database connected:", url);
});

db.on("error", err => {
  console.error("connection error:", err);
});
Enter fullscreen mode Exit fullscreen mode

尝试连接数据库。你应该看到如下日志:

已连接到数据库。

创建模型

在 Mongoose 中,您需要使用模型来创建、读取、更新或删除MongoDB 集合中的项目。

要创建模型,您需要创建一个 Schema。Schema 允许您**定义集合中条目**的结构。此条目也称为文档。

创建模式的方法如下:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const schema = new Schema({
  // ...
});
Enter fullscreen mode Exit fullscreen mode

您可以在 Schema 中使用10 种不同的值。大多数情况下,您会使用以下六种:

  • 细绳
  • 数字
  • 布尔值
  • 大批
  • 日期
  • 对象ID

让我们将其付诸实践。

假设我们想为街头霸王数据库创建角色。

在 Mongoose 中,通常的做法是将每个模型放在一个单独的文件中。Character.js因此,我们首先创建一个文件,Character.js并将其放置在models文件夹中。

project/
    |- models/
        |- Character.js
Enter fullscreen mode Exit fullscreen mode

在 中Character.js,我们创建一个characterSchema

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const characterSchema = new Schema({
  // ...
});
Enter fullscreen mode Exit fullscreen mode

假设我们想将两件事保存到数据库中:

  1. 角色名称
  2. 他们的终极技能名称

两者都可以用字符串表示。

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const characterSchema = new Schema({
  name: String,
  ultimate: String
});
Enter fullscreen mode Exit fullscreen mode

一旦我们创建了characterSchema,我们就可以使用 mongoose 的model方法来创建模型。

module.exports = mongoose.model("Character", characterSchema);
Enter fullscreen mode Exit fullscreen mode

创建角色

假设你有一个名为 的文件index.js。本教程中我们将在这里执行 Mongoose 操作。

project/
    |- index.js
    |- models/
        |- Character.js
Enter fullscreen mode Exit fullscreen mode

首先,你需要加载角色模型。你可以使用 来完成require

const Character = require("./models/Character");
Enter fullscreen mode Exit fullscreen mode

假设你想创建一个名为 Ryu 的角色。Ryu 的终极技能是“真红波动拳”。

要创建 Ryu,请使用new,后跟您的模型。在本例中,它是new Character

const ryu = new Character({
  name: "Ryu",
  ultimate: "Shinku Hadoken"
});
Enter fullscreen mode Exit fullscreen mode

new Character在内存中创建字符。它尚未保存到数据库。要保存到数据库,您可以运行该save方法

ryu.save(function(error, document) {
  if (error) console.error(error);
  console.log(document);
});
Enter fullscreen mode Exit fullscreen mode

如果您运行上面的代码,您应该在控制台中看到它。

Ryu 已保存至数据库。

Promises 和 Async/await

Mongoose 支持 Promise。它能让你写出更漂亮的代码,像这样:

// This does the same thing as above
function saveCharacter(character) {
  const c = new Character(character);
  return c.save();
}

saveCharacter({
  name: "Ryu",
  ultimate: "Shinku Hadoken"
})
  .then(doc => {
    console.log(doc);
  })
  .catch(error => {
    console.error(error);
  });
Enter fullscreen mode Exit fullscreen mode

await如果您有异步功能,您也可以使用关键字。

如果 Promise 或 Async/Await 代码对您来说很陌生,我建议您在继续阅读本教程之前阅读“JavaScript async 和 await” 。

async function runCode() {
  const ryu = new Character({
    name: "Ryu",
    ultimate: "Shinku Hadoken"
  });

  const doc = await ryu.save();
  console.log(doc);
}

runCode().catch(error => {
  console.error(error);
});
Enter fullscreen mode Exit fullscreen mode

注意:在本教程的其余部分,我将使用 async/await 格式。

独特性

new Character每次使用和 时,Mongoose 都会向数据库中添加一个新角色save。如果运行上述代码三次,数据库中应该会出现三个 Ryus。

数据库中有三个 Ryus。

我们不想在数据库中有三个 Ryu。我们只想拥有一个 Ryu。为此,我们可以使用unique选项。

const characterSchema = new Schema({
  name: { type: String, unique: true },
  ultimate: String
});
Enter fullscreen mode Exit fullscreen mode

unique选项创建唯一索引。它确保我们不能有两个具有相同值的文档(name在本例中)。

为了unique正常工作,您需要清除 Characters 集合。要清除 Characters 集合,您可以使用以下命令:

await Character.deleteMany({});
Enter fullscreen mode Exit fullscreen mode

现在尝试将两个 Ryu 添加到数据库中。您将得到一个E11000 duplicate key error。您将无法保存第二个 Ryu。

重复密钥错误.png

在继续本教程的其余部分之前,让我们先将另一个角色添加到数据库中。

const ken = new Character({
  name: "Ken",
  ultimate: "Guren Enjinkyaku"
});

await ken.save();
Enter fullscreen mode Exit fullscreen mode

数据库包含两个字符。

检索字符

Mongoose 为您提供了两种从 MongoDB 中查找内容的方法。

  1. findOne:获取一个文档。
  2. find:获取文档数组

找到一个

findOne 返回找到的第一个文档。您可以指定任何要搜索的属性。让我们搜索Ryu

const ryu = await Character.findOne({ name: "Ryu" });
console.log(ryu);
Enter fullscreen mode Exit fullscreen mode

从数据库中找到了 Ryu。

寻找

find 返回一个文档数组。如果您指定要搜索的属性,它将返回符合查询条件的文档。

const chars = await Character.find({ name: "Ryu" });
console.log(chars);
Enter fullscreen mode Exit fullscreen mode

梳理数据库并找到一个名叫 Ryu 的角色。

如果您没有指定要搜索的任何属性,它将返回包含集合中所有文档的数组。

const chars = await Character.find();
console.log(chars);
Enter fullscreen mode Exit fullscreen mode

在数据库中找到两个字符。

更新角色

假设 Ryu 有三个特殊动作:

  1. 波多肯
  2. 升龙轩
  3. 龙卷战风阁

我们想将这些特殊动作添加到数据库中。首先,我们需要更新我们的CharacterSchema

const characterSchema = new Schema({
  name: { type: String, unique: true },
  specials: Array,
  ultimate: String
});
Enter fullscreen mode Exit fullscreen mode

然后,我们使用以下两种方式之一来更新角色:

  1. 使用findOne,然后使用save
  2. 使用findOneAndUpdate

找到一个并保存

首先,我们用来findOne获取 Ryu。

const ryu = await Character.findOne({ name: "Ryu" });
console.log(ryu);
Enter fullscreen mode Exit fullscreen mode

然后,我们更新 Ryu 以包含他的特殊动作。

const ryu = await Character.findOne({ name: "Ryu" });
ryu.specials = ["Hadoken", "Shoryuken", "Tatsumaki Senpukyaku"];
Enter fullscreen mode Exit fullscreen mode

修改完之后ryu我们运行save

const ryu = await Character.findOne({ name: "Ryu" });
ryu.specials = ["Hadoken", "Shoryuken", "Tatsumaki Senpukyaku"];

const doc = await ryu.save();
console.log(doc);
Enter fullscreen mode Exit fullscreen mode

已更新 Ryu。

findOneAndUpdate

findOneAndUpdate和MongoDB的方法是一样的findOneAndModify

在这里,您搜索 Ryu 并同时传递您想要更新的字段。

// Syntax
await findOneAndUpdate(filter, update);
Enter fullscreen mode Exit fullscreen mode
// Usage
const doc = await Character.findOneAndUpdate(
  { name: "Ryu" },
  {
    specials: ["Hadoken", "Shoryuken", "Tatsumaki Senpukyaku"]
  }
);

console.log(doc);
Enter fullscreen mode Exit fullscreen mode

已更新 Ryu。

findOne + save 与 findOneAndUpdate 之间的区别

两个主要区别。

首先,的语法比findOne` + `save更易于阅读findOneAndUpdate

第二,findOneAndUpdate不触发save中间件。

findOnesavefindOneAndUpdate由于这两个差异,我随时都会选择+ 。

删除角色

删除角色有两种方法:

  1. findOne+remove
  2. findOneAndDelete

使用 findOne + remove

const ryu = await Character.findOne({ name: "Ryu" });
const deleted = await ryu.remove();
Enter fullscreen mode Exit fullscreen mode

使用 findOneAndDelete

const deleted = await Character.findOneAndDelete({ name: "Ken" });
Enter fullscreen mode Exit fullscreen mode

快速摘要

您学习了如何使用 Mongoose 来执行以下操作:

  1. 连接到数据库
  2. 创建、读取、更新和删除文档

感谢阅读。本文最初发布在我的博客上。如果您想阅读更多文章来帮助您成为更优秀的前端开发人员,请订阅我的新闻通讯。

文章来源:https://dev.to/zellwk/mongoose-101-5mm
PREV
在 Express 中使用 Async/await
NEXT
如何使用 CSS Grid 创建日历 创建 HTML