MoongoDB

1. 数据库概述及安装


1.1 使用数据库目的

  • 动态网站中的数据都是存储在数据库中的
  • 数据库可以用来持久存储客户端通过表单收集的用户信息
  • 数据库软件本身可以对数据进行高效的管理

http://www.czxy.com/article?id=1
http://www.czxy.com/article?id=2

不同的请求参数,动态的对应可能不同的页面


1.2 什么是数据库

数据库即存储数据的仓库,可以将数据进行有序的分门别类的存储

它是独立于语言之外的软件,可以通过 API 去操作它

常见的数据库软件有:mysql、mongoDB、oracle

mongoDB


1.3 MongoDB 安装

下载:MongoDB Community Server

MongoDB Compass


1.4 可视化软件

MongoDB可视化操作软件,是使用图形界面操作数据库的一种方式

下载:MongoDB Compass

MongoDB Compass

可视化操作软件


1.5 数据库相关概念

在一个数据库软件中可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据)

术语 名称 说明
database 数据库 mongoDB数据库软件中可以建立多个数据库
collection 集合 一组数据的集合,可以理解为 JS 中的数组
document 文档 一条具体的数据,可以理解为 JS 中的对象
field 字段 文档中的属性名称,可以理解为 JS 中的对象属性

2. MongoDB 连接


2.1 Mongoose 操作

使用 Node.js 操作 MongoDB 数据库需要依赖第三方包 mongoose

下载:npm install mongoose


2.2 MongoDB 启动

启动命令:在命令行工具中运行(管理员权限)

  1. net stop mongoDB
  2. net start mongoDB

否则 MongoDB 将无法连接


2.3 数据库连接

使用 mongoose 提供的 connect 方法即可连接数据库

View code
// 引入操作数据库模块(第三方模块)
const mongoose = require('mongoose');

// 数据库连接
mongoose.connect('mongodb://localhost/playground', {
        useNewUrlParser: true,
        useUnifiedTopology: true // 两行解决两个报错问题
    })
    .then(() => console.log('数据库连接成功')) // 连接成功
    .catch(err => console.log(err, '数据库连接失败')); // 连接失败

2.4 创建数据库

在 MongoDB 中不需要显式创建数据库,如果正在使用的数据库不存在,MongoDB 会自动创建


3. MongoDB 增删改查


3.1 创建集合

  1. 对集合设定规则(创建 mongoose.Schema 构造函数)
const courseSchema = new mongoose.Schema({
    name: String, // 名称
    author: String, // 作者
    isPublished: Boolean // 是否发布
});
  1. 创建集合(创建实例)

语法:mongoose.model('集合名称', 集合规则)

例:const Course = mongoose.model('Course', courseSchema)

注意:集合名称需首字母大写,在数据库里的名称是 courses


3.2 创建文档

创建文档实际上就是向集合中插入数据,有两中方法:

方法一:创建文档
// 1. 创建集合实例
const course = new Course({
    name: 'Node.js course',
    author: '黑马讲师',
    tags: ['node', 'backend'],
    isPublished: true
});
// 2. 将数据保存到数据库中
course.save();
方法二:插入文档(两种形式)
// 第一种
Course.create({ name: 'Node.js 基础', author: 'wzq1', isPublished: true }, (err, result) => {
    console.log(err); // 输出错误信息
    console.log(result); // 输出插入的内容
});

// 第二种
Course.create({ name: 'Node.js 基础', author: 'wzq2', isPublished: true })
    .then(result => console.log(result)) // 输出插入的内容
    .catch(err => console.log(err)); // 输出错误信息

3.3 导入数据

语法:mongoimport -d 数据库名称 -c 集合名称 --file 要导入的数据文件

成功导入6条数据

如果找到 mongoimport 命令报错:

找到 mongodb 数据库的安装目录:C:\Program Files\MongoDB\Server\4.4\bin

将安装目录下的 bin 目录放置在系统环境变量中 Path 中

如果发现 MongoDB 里面 bin 文件夹下缺少 mongoimport 文件:

下载:MongoDB Database Tools

解压后文件内 bin 目录下的文件全复制到 mongodb 数据库的 bin 目录下

MongoDB Database Tools

注意:运行 mongoimport 模块的时候必须退出当前数据库连接


3.4 查询文档

以下两个方法它们都可传递一个对象作为查找条件(条件为空表示所有)

  • 查询一条数据:findOne 方法,返回数据对象

    如果查询条件匹配了多个文档,那么将会返回第一个文档

User.findOne({ name: '张三' }).then(result => console.log(result));
  • 查询多条数据:find 方法,返回数据数组
// 查询 User 集合中的所有文档
User.find().then(result => console.log(result));

// 查询 id
User.find({ _id: '5c09f2b6aeb04b22f846096a' }).then(result => console.log(result));
设置查询条件
// 查询年龄大于20小于40
User.find({ age: { $gt: 20, $lt: 40 } }).then(result => console.log(result));

// 查询爱好包含吃饭的
User.find({ hobbies: { $in: ['吃饭'] } }).then(result => console.log(result));

// 查询 name email 字段(_id字段会默认显示)
User.find().select('name email').then(result => console.log(result));

// 查询 name email 字段(不显示_id字段)
User.find().select('name email -_id').then(result => console.log(result));

// 根据年龄升序排序
User.find().sort('age').then(result => console.log(result));

// 根据年龄降序排序
User.find().sort('-age').then(result => console.log(result));

// skip 跳过多少条数据  limit 限制查询几条数据(常用分页)
User.find().skip(2).limit(3).then(result => console.log(result));

3.5 删除文档

以下两个方法它们都可传递一个对象作为查找条件(条件为空表示所有)

  • 删除一条数据:findOneAndDelete,返回数据对象

    如果查询条件匹配了多个文档,那么将会删除第一个匹配的文档

// 删除年龄是20的第一条数据
User.findOneAndDelete({ age: 20 }).then(result => console.log(result))
  • 删除多条数据:deleteMany

    返回删除结果对象:{ n: 5, ok: 1, deletedCount: 5 }

    • n:匹配总数量
    • ok:是否成功(1:成功,0:失败)
    • deletedCount:删除的数量
// 删除所有数据
User.deleteMany().then(result => console.log(result))

3.6 修改文档

  • 修改一条数据:updateOne

    如果查询条件匹配了多个文档,那么将会删除第一个匹配的文档

    返回删除结果对象:{ n: 1, nModified: 1, ok: 1 }

    • n:匹配总数量
    • ok:是否成功(1:成功,0:失败)
    • nModified:修改的数量
// 修改 name 是李四的文档,age 改为 18,name 改为'李狗蛋'
User.updateOne({ name: '李四' }, { age: 18, name: '李狗蛋' }).then(result => console.log(result));
  • 修改多条数据:updateMany,返回删除结果对象
// 修改所有文档的 age 改为 66
// User.updateMany({}, { age: 66 }).then(result => console.log(result));

3.6 mongoose 验证

在创建集合规则时,可为当前字段设置多项验证规则

  • 指定数据类型:type: 数据类型

  • 是否必填字段:required: 布尔值

  • 最小长度:minlength: 数字(max同)

  • 是否去除两端空格:trim: 布尔值

  • 最小不得小于:min: 数字

  • 最大不得大于:max: 数字(max同)

  • 默认值:default: 值

  • 指定分类:enum: ['类型1', '类型2', ...]

  • 自定义验证条件:validate:{validator:v => v && v.length>2}

View code
const postSchema = new mongoose.Schema({
    title: { // 标题
        type: String, // 数据类型
        // 自定义错误提示:以数组形式,设置第二个参数
        required: [true, '标题为必填项'], // 必填字段
        minlength: [2, '长度不能小于2'], // 最小长度2
        maxlength: 6, // 最大长度6
        trim: true // 去除两端空格
    },
    age: { // 年龄
        type: Number,
        min: 18, // 下限(不得小于)
        max: 99 // 上限(不得大于)
    },
	publishDate: {
	    type: Number,
	   default: Date.now // 存为时间戳
    },
    category: { // 分类
        type: String,
        enum: { // 指定分类
            values: ['html', 'css', 'js'], // 仅允许指定的值
            message: '不在类别目录中' // 自定义错误提示
        }
        // enum: ['html', 'css', 'js']
    },
    author: { // 作者
        type: String,
        validate: { // 自定义验证条件
            validator: v => { // 验证器,v:要验证的值
                return v && v.length > 2 // 设置条件,需返回布尔值
            },
            message: '传入的值不符合条件' // 自定义错误提示
        }
    }
});

可自定义验证失败提示

  • 单项验证规则:验证规则: [规则参数, '失败提示']

    例:required: [true, '标题为必填项']

    解:当前为必填字段,如果不填就提示:标题为必填项

  • 多项验证规则:message: '失败提示'

enum: { // 指定分类
    values: ['html', 'css', 'js'], // 仅允许指定的值
    message: '不在类别目录中' // 自定义错误提示
}

获取错误信息error.errors['字段名称'].message

.then(result => console.log(result)) // 输出插入成功的文档
    .catch(error => { // 输出插入失败的信息
    const err = error.errors; // 错误对象
    for (let attr in err) { // 可能有多条错误信息,遍历错误对象
        console.log(err[attr]['message']) // 输出每条错误提示
    }
});

3.7 集合关联

通常不同集合的数据之间是有关系的

如:文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联

  1. 使用 id 对集合进行关联
  2. 使用 populate 方法进行关联集合查询
// 用户集合
const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } })); 
// 文章集合
const Post = mongoose.model('Post', new mongoose.Schema({
    title: { type: String },
    // 使用ID将文章集合和作者集合进行关联
    author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}));
// 联合查询
Post.find()
    .populate('author')
    .then(result => console.log(result));

关联集合


posted @ 2020-11-12 18:56  今夜星河漫漫  阅读(190)  评论(0)    收藏  举报