1. 简介
MongoDB是一个基于分布式文件存储的数据库,操作语法与JavaScript类似,容易上手。它与mysql不一样,mysql操作的是表格,即结构化数据,而mongodb操作的是json非结构化数据。下载地址https://www.mongodb.com/try/download/community
数据库是按照数据结构来组织、存储和管理数据的应用程序
,主要作用就是管理数据
,对数据进行增删改查。
Mongodb数据库在使用前,需要在终端执行mongod
来打开数据库服务端,在终端执行mongo
打开客户端,通过相关命令来完成数据库的增删改查。当然也可以下载Mongoose
包来通过代码完成对Mongodb
数据库的增删改查。
相比纯文件管理数据,数据库管理数据有如下特点:
Mongodb中有三个重要概念:
数据库(database):是一个数据仓库,数据库服务下可以创建很多数据库,数据库中可以存放很多集合
集合(collection):集合类似于 JS 中的数组,在集合中可以存放很多文档
文档(document):档是数据库中的最小单位,类似于 JS 中的对象
理解:
- 一个JSON文件好比是一个
数据库
,一个Mongodb服务下可以有N个数据库
- JSON文件中的一级属性的数组值好比是
集合
- 数组中的对象好比是
文档
- 对象中的属性也可以称为
字段
一般情况下:
一个项目使用一个数据库
一个集合会存储同一种类型的数据
2. 操作命令
1.显示所有的数据块:show dbs
2.切换到指定的数据库,如果数据库不存在会自动创建数据库:use 数据库名
3.显示当前数据库:db
4.删除当前数据库:先use 库名
,再db.dropDatabase()
5.创建集合:db.createCollection(‘集合名称’)
6.显示当前数据库中的所有集合:show collections
7.删除某个集合:db.集合名.drop()
8.重命名集合:db.集合名.renameCollection(‘newName’)
9.插入文档:db.集合名.insert(文档对象)
10.查询文档:db.集合名.find(查询条件)
- _id是mongodb自动生成的唯一编号,用来唯一标识文档
11.更新文档:
- db.集合名.update(查询条件,新的文档)
- db.集合名.update({name:’张三’},{$set:{age:19}})
12.删除文档:db.集合名.remove(查询条件)
3. Mongoose
Mongoose
是一个对象文档模型库,主要作用就是方便使用代码操作mongodb
数据库。
因为它有事一个工具包,所以在通过npm init
创建一个包后,就可以在该文件夹下使用npm i mongoose
来下载该包。
3.1 通过mongoose连接上Mongodb数据库
在下载Mongoose工具包后,在该文件夹下创建一个js文件,添加以下程序即可完成连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');
mongoose.connection.once('open', ()=>{ console.log('连接成功'); });
mongoose.connection.on('error', ()=>{ console.log('连接失败'); });
mongoose.connection.on('close', ()=>{ console.log('连接关闭'); });
setTimeout( () => { mongoose.disconnect(); }, 2000);
|
3.2 Mongoose插入文档
对于文档的插入操作,是在连接成功的回调函数中执行。在下面程序中,需要注意的是:在旧版本中 Model.create()
的第二个参数是一个回调函数
用来捕获成功或异常。但是最新版本中,Model.create()
中就没有第二个参数了
,而是返回了一个 Promise
对象,我们将采用 then
方法 和 catch
方法来捕获状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: String, author: String, price: Number }); let BookModel = mongoose.model('books', BookSchema); BookModel.create({ name: '西游记', author: '吴承恩', price: 19.9 }).then((data) => { console.log(data); }).catch((res) => { console.log(res); }); mongoose.disconnect(); });
|
3.3 字段类型
文档结构可选的常用字段类型列表:
类型 |
描述 |
String |
字符串 |
Number |
数字 |
Boolean |
布尔值 |
Array |
数组,也可以使用[]来标识 |
Date |
日期 |
Buffer |
Buffer对象 |
Mixed |
任意类型,需要使用mongoose.Schema.Types.Mixed指定 |
Objectld |
对象ID,需要使用mongoose.Schema.Types.ObjectId指定 |
Decimal128 |
高精度数字,需要使用mongoose.Schema.Types.Decimal128指定 |
测试程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean, tags: Array, pub_time: Date }); let BookModel = mongoose.model('books', BookSchema);
BookModel.create({ name: '西游记', author: '吴承恩', price: 19.9, is_hot: true, tags: ['鬼怪', '励志', '社会'], pub_time: new Date() }).then((data) => { console.log(data); mongoose.disconnect(); }).catch((res) => { console.log(res); mongoose.disconnect(); }); });
|
3.4 字段值验证
Mongoose有一些内建验证器,可以对字段值进行验证
1.必填项
1 2 3 4
| title: { type: String, required: true },
|
2.默认值
1 2 3 4
| author: { type: String, default: '匿名' },
|
3.枚举值
1 2 3 4
| gender: { type: String, enum: ['男','女'] },
|
4.唯一值
1 2 3 4
| username: { type: String, unique: true },
|
注意:
unique 需要 重建集合 才能有效果
永远不要相信用户的输入,需要检查后再插入数据库
测试程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: { type: String, required: true, unique: true }, author: { type: String, default: '匿名' }, style: { type: String, enum: ['言情', '城市', '志怪', '恐怖'] } }); let BookModel = mongoose.model('books', BookSchema);
BookModel.create({ name: '西游记', author: '吴承恩', style: '言情' }).then((data) => { console.log(data); mongoose.disconnect(); }).catch((res) => { console.log(res); mongoose.disconnect(); }); });
|
3.5 Mongoose删除和更新文档
下面程序需要注意的是,由于版本的问题,现在高版本已经不支持BookModel.deleteMany({}, (err, data) => {});
这种回调的写法了。
1.通过以下方式来完成删除操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean }); let BookModel = mongoose.model('novels', BookSchema);
BookModel.deleteOne({_id: '66e65604f92fdec9fa0a7f53'}).then((data) => {console.log(data);}).catch((res)=>{console.log('删除失败~~~');return;}); BookModel.deleteMany({is_hot: false}).then((data) => {console.log(data);}).catch((res)=>{console.log('删除失败~~~');return;}); });
|
2.通过以下方式来完成更新操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean }); let BookModel = mongoose.model('novels', BookSchema); BookModel.updateOne({name: '名侦探柯南'}, {price: 13.9}).then((data) => {console.log(data);}).catch((res)=>{console.log('更新失败~~~');return;}); BookModel.updateMany({is_hot: true}, {price: 19.9}).then((data) => {console.log(data);}).catch((res)=>{console.log('更新失败~~~');return;}); });
|
3.6 读取文档
1.普通读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| mongoose.connection.once('open', ()=>{ let BookSchema = new mongoose.Schema({ name: String, author: String, price: Number, is_hot: Boolean }); let BookModel = mongoose.model('novels', BookSchema); BookModel.findOne({name: '名侦探柯南'}).then((data) => {console.log(data);}).catch((res)=>{console.log('读取失败~~~');return;}); BookModel.findById('66e65688565eb1640b878f88').then((data) => {console.log(data);}).catch((res)=>{console.log('读取失败~~~');return;}); BookModel.find({is_hot: true}).then((data) => {console.log(data);}).catch((res)=>{console.log('读取失败~~~');return;}); });
|
2.运算符
在mongodb不能直接使用>、<、>=、<=、!==
等运算符,需要使用替代符号:
>
使用$gt
<
使用$lt
>=
使用$gte
<=
使用$lte
!==
使用$ne
1 2 3 4 5 6 7 8 9
| BookModel.find({ price: {$lt: 30} }).then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
|
3.逻辑运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| BookModel.find({ $or: [{name: '名侦探柯南'},{name: '海贼王'}] }).then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
BookModel.find({ $and: [{price: {$gt: 15}}, {price: {$lt:30}}] }).then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
|
4.正则匹配
条件中可以直接使用JS的正则语法,通过正则可以进行模糊查询
1 2 3 4 5 6 7 8 9
| BookModel.find({ name: /柯/ }).then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
|
5.个性化读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| BookModel.find().select({ name: 1, author: 1, _id: 0 }).then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
BookModel.find().select({ name: 1, author: 1, _id: 0}) .sort({price: 1}) .then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
BookModel.find().select({ name: 1, author: 1, _id: 0}) .sort({price: -1}) .skip(3) .limit(2) .then((data) => { console.log(data); }).catch((res)=>{ console.log('读取失败~~~'); return; });
|
最后如果想要操作更加的简单,可以使用Mongodb的图形化工具,比如说Navicat等。