下载

npm i mongoose -s

连接数据库

const mongoose = require("mongoose");
mongoose.connect(dbURL); const db = mongoose.connection; db.on("error", () => {
console.log("链接失败");
});
db.on("open", () => {
console.log("链接成功");
});

创建表结构Schema

Schema相当于MySql的表结构

通过定义Schema来约束数据的类型,支持以下类型数据

类型 作用
String 定义字符串
Number 定义数字
Date 定义日期
Buffer 定义二进制
Boolean 定义布尔值
Mixed 定义混合类型
ObjectId 定义对象ID
Array 定义数组
Decimal128
Map

约束能用对象的方法描述数据类型 是否必须 是否重复 默认值 等,如下定义了一个用户表结构

注意:如果定义表结构时没有定义_id,mongoose会自己添加一个该字段,该字段不会重复,类型为ObjectId,通过findById()查询

const userSachem = new mongoose.Schema(
{
name: {
type: String,
required: true, //! 必须
},
email: {
type: String,
required: true,
unique: true, //! 不重复
},
passWord: {
type: String,
required: true,
},
avatar: {
type: String,
default: null, //! 默认值
},
bio: String, //! 默认没有可以不写
},
{
timestamps: true, //! 添加`createdAt updatedAt`创建时间和更新时间两个字段
}
);

如果在定义了结构后需要添加新字段,在实例上使用add()方法

创建表model

通过mongoose.model(name,sechem)来创建表结构构造器,通过传入数据来实例化构造器获得具体的表

注意:在这一步的时候数据库已经有了表,表名全是小写且表明为name加上s,如这里会创建表users

const User = mongoose.model("User", userSechem);

通过上面的操作就获得了表的构造函数,接下来就可以向里面进行增删改查了

有三种方法在表内增加数据:

通过实例化数据:

  • 创建表数据实例化model

通过传入具体的数据来实例化表,能获得一条具体的表数据,类型为Mongoose Documents,向数据库中查找到的也是这种类型数据

const user = new User(userData);
  • 保存save

获得具体的表后只需要调用Model.prototype.save就会把数据存入数据库中 注意:该方法为异步方法

await user.save();

通过Model.create方法:

通过表构造器的静态方法create自动在表中插入新的数据

该方法可以接收多个插入数据,最后的回调函数参数根据数据量决定

该方法支持两种调用:

  • 错误优先的回调
  • async await
const users = await User.create(
{ name: "1", email: "123@qq.com", passWord: "123" },
{ name: "2", email: "456@qq.com", passWord: "456" },
{ name: "3", email: "789@qq.com", passWord: "789" }
);
res.status(200).json(users); // users是数组 // 或者
User.create(
{ name: "str", email: "159@163.com", passWord: "159" },
{ name: "1", email: "123@qq.com", passWord: "123" },
{ name: "2", email: "456@qq.com", passWord: "456" },
{ name: "3", email: "789@qq.com", passWord: "789" },
(err, doc1, doc2, doc3) => {
if (err) {
return err;
}
res.status(200).json({ doc1, doc2, doc3 });
}
);

通过Model.insertMany方法

该方法与create的区别是它接收的第一个参数是数据组成的数组,多条数据只会插入第一条

const user = await User.insertMany({ name: "1", email: "123@qq.com", passWord: "123" });
const users = await User.insertMany([
{ name: "2", email: "456@qq.com", passWord: "456" },
{ name: "3", email: "789@qq.com", passWord: "789" },
]);


查找数据

通过Model.find方法

不传入参数会查找该表的所有数据

该方法返回值始终是数组

第一个参数

指定数据的某个键进行查找,键也能是正则表达式

const data = await User.find({ name: /\d/ });

限制查找范围,通过内置的字段限制某个字段的范围,$where函数参数来指定查询的限制范围

const data = await User.find({
name: { $gt: 1 },
$where: () => this.passWord == parseInt(this.email),
}); // 查找name大于1且密码和邮箱一样的

还能通过$and $or $not等参数来决定查找的范围

const data = await User.find({
$or: [{ $and: [{ name: /[1,2]/ }, { email: /(@qq.com)$/ }] }, { name: /\w+/ }],
}); // 查找 name为1或2且为QQ邮箱 或 name为字符串 的数据

如果查找的是对象中的属性用字符串做键或者嵌套查找

注意 嵌套查找必须顺序一致

// 查找这条数据 { name: "4", email: "357@163.com", passWord: "357", bio: { head: 123, foot: 789 } }
const datas = await User.find({ "bio.head": 123 }); // 字符串查找
const datas = await User.find({ bio: { head: 123, foot: 456 } }); // 嵌套对象查找 对象要写全且顺序不能改变,里面只能用具体的数据,不能用正则表达式或其它的限制

如果查找的是数组中的某项

// 有这两条数据 { name: "4", email: "357@163.com", passWord: "357", bio: [123, 456, "hahaha"] }
// { name: "5", email: "258@163.com", passWord: "258", bio: [123, 789, "haha"] }
const datas = await User.find({ bio: 123 }); // 如果数组中有一个数据符合就会找到 也能像上面一样用特殊参数指定范围
const datas = await User.find({ bio: { $all: [123, 456] } }); // 查找含有这两个值 只能找到第二条
const datas = await User.find({ bio: { $in: [456, 789] } }); // 查找这两个值中的任意一条 两条都能找到
const datas = await User.find({ "bio.1": { $gt: 456 } }); // 使用下标指明指定数据的范围 这里找到第二条

如果查找的是数组对象中的某项

// 有这两条数据
{
name: "4",
email: "357@163.com",
passWord: "357",
bio: [
{ head: 123, foot: 456 },
{ head: 456, foot: 789 },
],
},
{
name: "5",
email: "258@163.com",
passWord: "258",
bio: [
{ head: 123, foot: 789 },
{ head: 789, foot: 456 },
],
}
const datas = await User.find({ bio: { head: 123, foot: 789 } }); // 数组中含有这个对象就会找到,对象属性要写全,不能只写部分,循序不能修改
const datas = await User.find({ "bio.foot": 789 }); // 数组中只要有一个对象符合就会找到,这里两个都会找到
const datas = await User.find({
bio: { $elemMatch: { foot: 456, head: { $gt: 100 } } }, // 使用$elemMatch 数组中拥有指定的对象就会找到,可以交换顺序,可以使用限制,但是不能使用正则
});

第二个参数

限制返回数据含有的数据

const data = await User.find({ name: /\d/ }, { name: 1, email: 1, _id: 0 }); // _id默认带着,这里忽略了

第三个参数

可以使用keip limit sort来对查询结果进行操作

const data = await User.find({ name: /\d/ }, null, { skip: 1 }); // 这里只会查找到 2 3

第二三个参数也能用链式调用的方法定义

查询的结果支持链式调用,可以使用一些方法再对结果进行操作,相当于把第二个参数写道外面了

  • select:设置查询结果的数据包含哪些键 接收列明字符串组成的数组,如果字符串前加上-则是不显示

    const datas = await User.find().select(["name", "-_id"]); // 查询所有数据 返回对象只有name
  • limit:限制查找结果的长度

  • skip:设置查找结果的起式位置

  • sort:对查找结果排序 接收列名字符串,按照从小到大排序,如果前面加上-则会从大到小排

    const datas = await User.find().sort("-name"); // str 3 2 1
    const datas = await User.find().sort("name"); // 1 2 3 str
  • count:返回查找结果的数量

  • lean:将结果返回为普通的js对象而不是查询得到的Mongoose Documents类型对象

常用的内置字段:

字段 说明
$or 或关系
$nor 或关系取反
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$ne 不等于
$in 在多个值范围内
$nin 不在多个值范围内
$all 匹配数组中多个值
$regex 正则,用于模糊查询
$size 匹配数组大小
$maxDistance 范围查询,距离(基于LBS)
$mod 取模运算
$near 邻域查询,查询附近的位置(基于LBS)
$exists 字段是否存在
$elemMatch 匹配内数组内的元素
$within 范围查询(基于LBS)
$box 范围查询,矩形范围(基于LBS)
$center 范围醒询,圆形范围(基于LBS)
$centerSphere 范围查询,球形范围(基于LBS)
$slice 查询字段集合中的元素(比如从第几个之后,第N到第M个元素

通过Model.findOne方法

该方法返回符合条件的第一条数据

通过Model.findById方法

通过每个数据的_id属性查询


通过Model.remove方法

不传入参数会删除该表的所有数据

该方法返回的是删除数据的条数,不会返回被删除数据

指定要删除数据的某个键,键也可以使用正则表达式

const remove = await User.remove({ name: /\d/ });

也可以先查找,然后用数据的remove方法

// 可以链式调用
const data = await User.find({ name: "1" }).remove();
// 也能迭代删除
const data = await User.find({ name: "2" });
data.forEach((item) => {
item.remove();
});

通过Model.findOneAndRemove方法

删除符合条件的第一条数据,并将这条数据返回

通过Model.findByIdAndRemove方法

通过_id删除


Model.update已经不支持

通过Model.updateOne Model.updateMany方法

该方法返回修改的信息,不是返回修改后的数据

先指定查询的条件,再在第二个参数放入修改的数据,第三个参数为一些设置

const datas = await User.updateOne({ name: "1" }, { $set: { name: "999" } }); // 将name为1的数据的name改为999

第三个参数如下,一般用不上

键名 默认值 说明
safe true 安全模式
upsert false 是没有这张表时是不是新建数据
setDefaultsOnInsert 如果upsert选项为true,在新建时插入文档定义的默认值
strict 以strict模式进行更新
overwrite false 禁用update-only模式,允许覆盖记录

通过修改find findOne findById找到的数据后调用save方法

const data = await User.find({ name: "999" }); // data只会是一个数组 如果是findOne findById则不是
data.forEach((item) => {
item.name = "1";
item.save();
});

通过findOneAndUpdate findByIdAndUpdate方法

是上面的语法糖,获得修改后的数据

mogoose 创建数据库并增删改查的更多相关文章

  1. django之创建第8-1个项目-数据库之增删改查/数据库数据显示在html页面

    1.为test.DB数据库预先创建下面数据 1    张三    16    2015-01-02    12    李四    17    2015-01-04    13    王五    14  ...

  2. 啊啊啊啊啊啊啊今天就写,炒鸡简单 数据库Sqlite的创建,库的增删改查

    啦啦啦啦啦啦啦 写这个不用多长时间,我直接写代码注释都是些语句,Sql语句和Api来操作数据库 ,语句的参数我会注释 SQLite数据库创建数据库需要使用的api:SQLiteOpenHelper必须 ...

  3. Android学习---数据库的增删改查(sqlite CRUD)

    上一篇文章介绍了sqlite数据库的创建,以及数据的访问,本文将主要介绍数据库的增删改查. 下面直接看代码: MyDBHelper.java(创建数据库,添加一列phone) package com. ...

  4. java jdbc 连接mysql数据库 实现增删改查

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

  5. 【转载】通过JDBC对MySQL数据库的增删改查

    通过JDBC进行简单的增删改查(以MySQL为例) 目录 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操 ...

  6. MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  7. Asp.net MVC4 使用EF实现数据库的增删改查

    EF的使用 步骤: (1)将EF添加到项目:在Model右击添加新建项 找到ADO.NET实体数据模型,接着... (2)实现数据库的增删改查       查询 (因为在Model中已经添加EF实体了 ...

  8. 使用EF实现数据库的增删改查

    EF的使用步骤:(1)将EF添加到项目:在Model右击添加新建项找到ADO.NET实体数据模型,接着…(2)实现数据库的增删改查查询(因为在Model中已经添加EF实体了,所以就可以在Control ...

  9. 开源工具DbUtils的使用(数据库的增删改查)

    开源工具DbUtils的使用(数据库的增删改查) 一.DbUtils简介: DBUtils是apache下的一个小巧的JDBC轻量级封装的工具包,其最核心的特性是结果集的封装,可以直接将查询出来的结果 ...

随机推荐

  1. Longhorn 企业级云原生分布式容器存储-券(Volume)和节点(Node)

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生分布式块存储解决方案设计架构和概念 Longhorn 企业级云原生容器存储解决方 ...

  2. windows中抓取hash小结(下)

    书接上回,windows中抓取hash小结(上) 指路链接 https://www.cnblogs.com/lcxblogs/p/13957899.html 继续 0x03 从ntds.dit中抓取 ...

  3. dockerfile中ENTRYPOINT与CMD的结合

    一.写在前面 我们在上篇小作文docker容器dockerfile详解对中dockerfile有了比较全面的认识,我们也提到ENTRYPOINT和CMD都可以指定容器启动命令.因为这两个命令是掌握do ...

  4. 内存吞金兽(Elasticsearch)的那些事儿 -- 认识一下

    背景及常见术语 背景 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene 基础之上. Lucene 可以说是当下最先进.高性能.全功能的搜索引擎库- ...

  5. NOIP 模拟 $32\; \rm Smooth$

    题解 \(by\;zj\varphi\) 很简单的贪心题. 开 \(B\) 个队列,每个队列存最后一次乘上的数为当前队列编号的数. 每次去所有队列中队首的最小值,不用开堆,因为开堆用于将所有数排序,但 ...

  6. 【java虚拟机】内存溢出与内存泄漏

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/7354857.html 一.基本概念 内存溢出:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提 ...

  7. 如何在 Go 中嵌入 Python

    如果你看一下 新的 Datadog Agent,你可能会注意到大部分代码库是用 Go 编写的,尽管我们用来收集指标的检查仍然是用 Python 编写的.这大概是因为 Datadog Agent 是一个 ...

  8. 【C语言】

    第3章 最简单的C程序设计 顺序程序设计 数据的表现形式及其运算 常量.变量.常变量.标识符 数据类型 整型.浮点型 整型数据的分类 最基本的整型类型 基本整型(int型):占2个或4个字节 短整型( ...

  9. go-Gorm

    软删除 如果模型中有 DeletedAt 字段,它将自动拥有软删除的能力!当执行删除操作时,数据并不会永久的从数据库中删除,而是将 DeletedAt 的值更新为当前时间.

  10. 自己封装一个Object.freeze()方法

    1.遍历所有属性和方法 2.修改遍历到的属性的描述 3.Object.seal() Object.defineProperty(Object,'freezePolyfill',{ value:func ...