# Mongoose - Node 应用

MongooseMongoDB 的一个对象模型工具,是基于 node-mongoldb-native 开发的 MongoDB nodes 驱动,可以在异步的环境下执行。

同时它也是针对 MongoDB 操作的一个对象模型库,封装了 MongoDB 对文档的的一些增删改查等常用方法,让 NodeJS 操作 Mongodb 数据库变得更加灵活简单。

由于 mongodb 的数据格式比较灵活,可以插入任何数据,不受限制。但实际开发项目中,数据格式是有一定的规范的,尤其是多人开发协作时。

如果存储的数据多以格式松散的数据为主,只有少量数据需要规范数据,可以直接选择 mongodb 数据库;如果大部分数据都需要规范数据存储格式,最好直接使用 mysql 数据库。

通过使用 Mongoose 来提供规范

  • 使用 Schema 定义数据格式的规范
  • 使用 Model 来规范 Collection

# mongoose 链接 mongodb

TIP

安装依赖:yarn add mongoose -S

当前安装的版本是 ^6.2.1

const mongoose = require("mongoose");

const url = "mongodb://localhost:27017";
const dbName = "blog";

mongoose.connect(`${url}/${dbName}`, {
  // 配置信息
});

const db = mongoose.connection;

db.on("error", (err) => {
  console.error(err);
});

// 链接成功
db.once("open", () => {
  console.log(`mongoose connect success`);
});

module.exports = mongoose;

# mongoose 定义规范

比如我们定一个 UserBlog 的数据规范,首先需要通过 Schema 来定义要保存字段的各种规范(是否必传,类型...),类似于 ts 的类型声明。然后使用这个规范,调用 model 生成规范即可。

TIP

  1. 引入模型规范后,传入的字段在 Schema 中未定义,会被忽略。

  2. 在通过 model 规范对应的 Collection 时,对应的集合名称写成小写即可。如:mongoose.model("集合名称", Schema规范);,存入到数据库中时会自动添加上复数的,比如集合名称是 blog, 会变成 blogs

  3. 在通过 model 规范对应的 Collection 时,对应的集合如果不存在,会自动创建。

# models/User.js

// 对应 User 的 Collection

const mongoose = require("../db");

// 用 Schema 定义数据规范
const UserSchema = mongoose.Schema(
  {
    username: {
      type: String,
      require: true,
      unique: true, // 唯一,不能重复
    },
    password: String,
    relname: String,
  },
  { timestamps: true } // 自动为数据添加创建和更新的时间戳
);

// Model 的规范Collection
// 注意点:数据库里是 users,我们这里可以直接写成 user,mongoose 会自动变成 users
const User = mongoose.model("user", UserSchema);
// 如果数据库里没有 user 这个 collection,会自动创建设置的 collection

module.exports = User;

# models/Blog.js

// 对应 Blog 的 Collection
const mongoose = require("../db");

// 用 Schema 定义数据规范
const BlogSchema = mongoose.Schema(
  {
    title: {
      type: String,
      required: true,
    },
    content: String,
    author: {
      type: String,
      required: true,
    },
  },
  { timestamps: true } // 自动为数据添加创建和更新的时间戳
);

const Blog = mongoose.model("blog", BlogSchema);

module.exports = Blog;

# mongoose 使用示例

# test/user.js

const User = require("../models/User");

(async () => {
  // 创建用户
  const lisi = await User.create({
    username: "lisi",
    password: "123456",
    relname: "李四",
    age: 20, // 不在数据规范内的数据插入不了
  });

  // 查询
  const result = await User.find();
})();

# test/blog.js

const Blog = require("../models/Blog");

!(async () => {
  // 新建博客
  const blogAdd = await Blog.create({
    title: "标题3",
    content: "标题3内容",
    author: "zhangsan",
  });

  console.log(blogAdd);

  // 获取博客列表,是数组
  const blogFind = await Blog.find({
    author: "zhangsan",
    title: /标题/, // 正则表达式表示模糊查询
  }).sort({ _id: -1 });

  console.log(blogFind);

  // 如果想指定返回的字段都有哪些,可以通过字符串来指定
  const blogFind = await Blog.findOne(
    {
      key: value,
    },
    "userId username password"
  ); // 在这里通过空格间隔来指定要返回的字符串

  // 获取单条是 json
  const blogFindById = await Blog.findById("6204a78db99ffa76b0ccc1a6");
  console.log(blogFindByTitle);

  // 修改博客
  const blogUpdate = await Blog.findOneAndUpdate(
    { _id: "6204a78db99ffa76b0ccc1a6" }, // 条件
    { content: "标题3的内容更新" },
    {
      new: true, // 默认 false,返回修改之前的数据,设置成 true 返回修改之后的数据
    }
  );

  console.log(blogUpdate);

  // 删除
  const blogDel = await Blog.findOneAndDelete({
    _id: "6204a78db99ffa76b0ccc1a6",
    author: "zhangsan",
  });

  console.log(blogDel);
})();

# 当前目录结构

  .
  ├── package.json
  ├── src
  │   ├── db.js
  │   ├── models
  │   │   ├── Blog.js
  │   │   └── User.js
  │   └── test
  │       ├── blog.js
  │       └── user.js
  └── yarn.lock