MongoDB 基础入门与进阶
一、简介
1、数据库
- 用于存储数据
- 数据库是一个独立的系统,和服务端语言无关
- 数据库有很多,对于前端工程师来说主要选择 MongoDB
2、NoSQL
NoSQL 的含义:Not only SQL
- 不仅仅是 SQL
- 泛指非关系型的数据库
- 数据存储的具体形式是 “键:值” 对的方式
- 通过降低数据安全性、减少对事物的支持、减少对复杂查询的支持,从而获得性能上的提升
3、MongoDB 概念
- 数据库(database)
- 集合(collection)
- 数据/文档(document)
二、MongoDB 安装
1、在 Mac 安装 MongoDB(服务端 和 客户端Compass)
Mac 安装 MongoDB:
- 安装 homebrew
1)首先在浏览器搜索:homebrew 或者输入网址:https://brew.sh
2)然后在终端输入如下命令,安装完成后可以输入如下命令验证,如果显示版本号则证明安装成功
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
// 验证
brew --version
- 用 homebrew 安装 MongoDB
1)继续在终端输入如下命令安装 MongoDB
brew install mongodb-community
2)如果不成功,可以先输入如下命令,执行后在输入 1)
brew tap mongodb/brew
// 1) 中的命令
brew install mongodb-community
3)启动 MongoDB
brew services start mongodb-community
4)验证安装启动成功,在终端直接输入 mongo
mongo
5)停止 MongoDB
brew services stop mongodb-community
- 安装客户端 Compass
1)在浏览器搜索 Compass 或输入该网址:https://www.mongodb.com/try/download/compass
2)安装完成后首先在终端启动 MongoDB,然后点击启动 Compass,点击 connect 出现如下图片表示连接成功
2、在 Mac 安装 MongoDB 的另一种方式
(1)下载 MongoDB
- MongoDB 官网下载地址:https://www.mongodb.com/try/download/community
- 创建软连接
ln -s /MongoDB安装位置/bin/mongod /usr/local/bin/mongod
ln -s /MongoDB安装位置/bin/mongo /usr/local/bin/mongo
- 创建配置文件
data:数据库目录
log:日志目录
conf:配置目录
# 数据库路径
dbpath=/MongoDB安装位置/mongo/data
# 日志输出文件路径
logpath=/MongoDB安装位置/mongo/log/mongo.log
# 错误日志采用追加模式
logappend=true
# 启用日志文件,默认启用
journal=true
# 若需要调试使用将其设置为 false,这个选项可以过滤掉一些无用的日志信息
quiet=true
# 端口号 默认 27017
port=27017
# 是否使用用户名和密码登录
#auth=true
#
fork=true
- 启动服务
mongod --conf /MongoDB安装位置/mongo/config/mongo.conf
3、在 Windows 安装 MongoDB
(1)下载与安装 MongoDB 数据库
- MongoDB 官网下载地址:https://www.mongodb.com/try/download/community
- 安装:一直点击下一步即可(记住安装位置)
(2)环境变量配置
- 鼠标放在桌面的“计算机”右键选择“属性”
- 在弹出的面板里面选择“高级系统设置”
- 选择“环境变量”
- 在“系统变量”里选择“Path”,然后点“编辑”
- 然后在“变量值”输入框的末尾加上安装 mongoDB 的路径(如果最后一个末尾没有分号,添加分号后再粘贴路径)
- 一般默认安装的地址是:C:\Program Files\MongoDB\Server\4.4.10\bin
- 点击“确定”退出环境变量配置
- 在命令控制台输入 “mongod --version”如果出现版本号就表明安装成功
(3)配置文件
三、MongoDB 使用
1、操作数据库(database)
(1)查看数据库
// 使用 mongodb
// mongo
show databases;
(2)选择数据库(新建数据库)
- 在 MongoDB 中选择不存在的数据库不会报错,后期当该数据库有数据时,系统自动创建会一个新的数据库
use 数据库名称;
// use test;
(3)删除数据库
- 通过 use 语法选择数据库
- 通过 db.dropDatabase() 删除数据库
// 通过 use 语法选择数据库
use 要删除的数据库名; // use test;
// 通过 db.dropDatabase() 删除数据库
db.dropDatabase();
2、操作集合(collections)
(1)查看集合
show collections;
(2)创建集合
db.createCollection('集合名称');
// dbcreateCollection('c1');
(3)删除集合
db.集合名.drop();
// db.c1.drop();
3、文档/数据(document)的增删改查(CRUD)
(1)新增数据
- 语法:db.集合名.insert(JSON数据)
- 说明:集合存在则直接插入数据;集合不存在则隐式创建集合再插入数据
- 注意:数据库或集合不存在会隐式创建;对象的键统一不加引号方便看,但查看集合数据时系统会自动加
use test2;
db.doc1.insert({username: 'lgk', age: 18});
MongoDB 会给每条数据增加全球唯一的 _id 键:
- _id 的组成:时间戳 + 机器码 + PID + 计数器
MongoDB 是否可以自定义 _id 值:
- 可以,只需要给插入的 JSON 数据增加 _id 键即可覆盖(不建议自定义)
db.doc1.insert({_id: 1001, username: 'zll', age: 18})
如何插入多条数据:
- 数组中写一个 JSON 数据即可
- MongoDB 底层使用 JS 引擎实现的,所以支持部分 JS 语法
db.doc1.insert([
{ username: 'zs', age: 18 },
{ username: 'ls', age: 18 }
])
// for(var i = 1; i < 10; i++) {
db.doc2.insert({us: 'a' + i, test: i + 10})
}
(2)查看数据
- 语法:db.集合名.find(条件 [, 查询的列])
- 条件:
查询所有数据: {} 或 不写
查询 username=zs 的数据 {username: ‘zs’}
查询 sex=male 且 age=10 的数据 {sex: ‘male’, age: 10}
查询的列(可选参数):不写是查询全部的列(字段)
只显示 age 字段的数据 ({}, {age: 1})
显示除了 age 字段的所有数据 ({}, {age: 0})
// 查询所有数据
db.doc1.find()
db.doc1.find({})
// 查询 username = zs 的数据
db.doc1.find({username: 'zs'})
// 只显示 age 字段
db.doc1.find({}, {age: 1})
// 显示非 age 字段
db.doc1.find({}, {age: 0})
语法升级(加上运算符):
- 语法:db.集合名.find({键: {运算符: 值}})
// 查询 age > 15
db.doc2.find({age: {$gt: 15}})
// 查询年龄是 12 15 18的数据
db.doc2.find({test: {$in:[12,15,18]}})
运算符 | 作用 |
---|---|
$gt | 大于 |
$gte | 大于等于 |
$lt | 小于 |
$lte | 小于等于 |
$ne | 不等于 |
$in | in |
$nin | not in |
(3)修改数据
- 语法:db.集合名.undate(条件, 新数据 [, 是否新增, 是否修改多条])
- 新数据是替换掉原数据
- 升级语法:db.集合名.undate({键: 值}, {修改器: {键: 值}} [, 是否新增, 是否修改多条])
- 是否新增:指条件匹配不到数据则插入
true:插入
false:不插入(默认) - 是否修改多条:指将匹配成功的数据都修改
true:是
false:否(默认)
修改器 | 作用 |
---|---|
$inc | 递增 |
$rename | 重命名列 |
$set | 修改列值 |
$unset | 删除列 |
// 替换
db.doc2.updat({us: 'a9'}, {user: '111'})
// 修改列值
db.doc2.update({us: 'a2'}, {$set: {us: 'as'}})
// 重命名列
db.doc2.update({us: 'a1'}, {$rename: {us: 'as'}})
// 递增:给 age 增加 10 岁
// 递减:增加 负值
db.doc2.update({us: 'a7'},{$inc: {age: 10}})
db.doc2.update({us: 'a6'},{$inc: {age: -2}})
// 删除
db.doc2.update({us: 'a4'}, {$unset: {test:''}})
一次性使用多个修改器:
db.doc2.update({us: 'a3'},{$rename: {us: 'user'},$set: {age: '12345'}})
(4)删除数据
- 语法:db.集合名.remove(条件 [, 是否删除一条])
- 是否删除一条
true:是
false:否(默认)
// 删除一条数据:
db.doc2.remove({}, true)
// 删除所有
db.doc2.remove({})
4、MongoDB 进阶
(1)排序(sort)和分页(limit)
排序(sort):
- 语法:db.集合名.find().sort(JSON数据)
- 说明:键:就是要排序的字段/列;值:1 表示升序,-1 表示降序
db.c1.find().sort({age: 1})
分页(limit):
- 语法:db.集合名.find().limit(数字) 或 db.集合名.find().skip(数字).limit(数字)
- 说明:skip 跳过指定数量(可选);limit 限制查询的数量
- 也可以结合 sort() 一起使用
- skip 计算公式:(当前页 - 1) * 每页显示条数
// 默认排序 -- 跳过 0 条 -- 展示 2 条数据
db.c1.find().limit(2)
db.c1.find().skip(0).limit(2)
// 默认排序 -- 跳过 1 条 -- 展示 3 条
db.c1.find().skip(1).limit(3)
// 降序 -- 跳过 1 条 -- 展示 3 条
db.c1.find().sort({age: -1}).skip(1).limit(3)
// 数据库有 1-10 数据,每页显示 2 条(共 5 页)
currentPage = 3
show = 2
skip = (currentPage - 1) * show
db.c1.find().skip(skip).limit(show)
(2)聚合查询
(3)索引
(4)权限机制
(5)备份还原
四、mongoose
1、mongoose 简介
- mongoose 中文网:http://www.mongoosejs.net/docs/guide.html
- mongoose 是 node 中提供操作 MongoDB 的模块,能够通过 node 语法实现对 MongoDB 数据库的增、删、改、查,从而实现用 node 写程序来管理 MongoDB 数据库
- 在项目中下载 mongoose 的命令
// npm
npm install mongoose --save
// yarn
yarn add mongoose
Schemas 约束:
- 用来约束 MongoDB 文档数据(哪些字段必须,哪些字段可选)
类型 | 作用 |
---|---|
String | 定义字符串 |
Number | 定义数字 |
Date | 定义日期 |
Buffer | 定义二进制 |
Boolean | 定义布尔值 |
Mixed | 定义混合类型 |
ObjectId | 定义对象ID |
Array | 定义数组 |
Models 模型:
- 一个模型对应一个集合,通过模型来管理集合中的数据
2、mongoose 使用
- 1、导入模块
// 1、导入模块
const mongoose = require('mongoose')
- 2、连接数据库
// 2、连接数据库
// 方法1:
// 本地默认 mongodb 服务地址
const url = 'mongodb://localhost:27017'
// 数据库名称
const dbname = 'shop'
// 配置
mongoose.set('useCreateIndex', true)
mongoose.set('useFindAndModify', false)
// 开始连接
mongoose.connect(`${url}/${dbname}`, {
useNewUrlParser: true,
useUnifiedTopology: true
})
// 连接对象
const db = mongoose.connection
db.on('error', err => {
console.log('数据库连接失败!!!', err)
})
db.once('open', () => {
console.log('数据库连接成功!')
})
// 方法2:
const db = mongoose.createConnection('mongodb://账号:密码@localhost:27017/databasename', {useNewUrlParser: true, useUnifiedTopology: true}).then(res => {
console.log('数据库连接成功!')
}).catch(err => {
console.log('----------------------------')
console.log('数据库连接失败!!!', err)
console.log('----------------------------')
})
- 3、设置数据模型(声明是哪个集合,限制字段个数和字段类型)
// 3、设置数据模型(声明是哪个集合,限制字段个数和字段类型)
const Model = db.model('对应的数据库集合名', {
username: { type: String, default: 'username' },
password: { type: String },
age: { type: Number },
sex: { type: String, default: 'male'},
addr: { type: String }
})
// 第 3 步 等价于 下面注释部分
//创建Schema对象(约束)
//var stuSchema = new Schema({
// username: {
// String,
// default: 'username'
// },
// password: String,
// age: Number,
// sex:{
// type: String,
// default:'male'
// },
// addr: String
//})
//将stuSchema映射到一个MongoDB collection并定义这个文档的构成
//var stuModle = mongoose.model('user',stuSchema)
- 4、创建实例操作(CRUD)
/**
* 增加(Create)
*/
// 增 —— save()
// const insertObj = new Model(数据对象)
const insertObj = new Model({
username: 'lgk',
password: '123456',
age: 12,
sex: 'male',
addr: 'nj'
})
// 方法1:
insertObj.save((err) => {
db.close()
})
// 方法2(推荐):
insertObj.save().then(res => {
return res
}).catch(err => {
console.log('插入数据失败!!! ' + err)
return false
})
// 增 —— create()
//Model.create({
// username: 'lgk',
// password: '123456',
// age: 12,
// sex: 'male',
// addr: 'nj'
//}, err => {
// console.log('插入数据失败!!! ' + err)
// return false;
//})
/**
* 删(Delete)
*/
// 方法1:
Model.remove/deleteOne/deleteMany(条件对象, err => { db.close() })
// 方法2(推荐):
Model.deleteOne(条件对象).then(res => {
return res.deletedCount
}).catch(err => {
console.log('删除数据失败!!! ' + err)
return false;
})
/**
* 改(Update)
*/
// 方法1:
Model.update/updateOne/updateMany(条件对象, 数据对象, (err) => { db.close() })
// 方法2(推荐):
Model.updateOne(条件对象, 数据对象).then(res => {
return res.nModified
}).catch(err => {
console.log('修改失败!!! ' + err)
return false
})
/**
* 查(Read)
*/
// 方法1:
Model.find/findOne(条件对象, 要显示的字段数据对象, (err, result) => { db.close() })
// 方法2(推荐):
Model.findOne(条件对象).then(res => {
return res
}).catch(err => {
console.log('修改失败!!! ' + err)
return false
})