1. MongoDB简介
- MongoDB是为快速开发互联网Web应用而设计的数据库系统。
- MongoDB的设计目标是极简、灵活、作为Web应用栈的一部分。
- MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存的是各种各样的JSON。(BSON)
1.1 下载MongoDB与安装
1.1.1 下载MongoDB
- 下载地址>>>
- MongoDB的版本偶数版本为稳定版,奇数版本为开发版。
- MongoDB对于32位系统支持不佳,所以3.2版本以后没有再对32位系统的支持。
1.1.2 Docker安装mongodb
- 查找docker中的mongo
- docker search mongo
- 拉取镜像
- docker pull mongo:4.0-xenial
- docker images
- 运行镜像
- docker run --name mongodb --restart always -p 27017:27017 -v mongodata:/data/db -d mongo:4.0-xenial --auth --bind_ip_all
- 设置权限
- docker exec -it a7e5d4e4ca69 mongo admin
- db.createUser({ user: 'admin', pwd: 'admin123456', roles: [ { role: "readWrite", db: "app" } ] });
1.3 Mongo基本概念
- 数据库(data)
- 集合(collection)
- 文档(document)
- 在MongoDB中,数据库和集合都不需要手动创建
- 当创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合
- 在MongoDB中,数据库和集合都不需要手动创建
1.2 Mongo基本操作
// 1. 查询所有数据库
show dbs;
show databases;
// 2. 进入到指定的数据库中
// 当创建文档是
use ${dbName}
// 3. 查看数据库中的集合
show collections;
// 4. 数据库的crud的操作
// 4.1 查询集合中的文档
db.test.find();
// 4.2 向集合中插入文档
- 向集合中插入一个或多个文档
- 向集合中插入文档时,如果没有给文档指定_id属性,则数据库会自动为文档添加_id
db.<collection>.insert(${doc})
// 例子:db.test.insert({name:"孙悟空",age:18,gender:"男"});
// 4.2.1 插入多个文档
db.<collection>.insert([${doc1},${doc2},${doc3}]);
// 3.2版本以后
db.<collection>.insertOne();
db.<collection>.insertMany();
// 4.3 查询
// 4.3.1 查询集合中所有符合条件的文档
db.<collection>.find()
// 4.3.2 通过id查询文档
db.<collection>.find({_id:""});
// 4.3.3 通过普通属性查询文档
db.<collection>.find({age:"", name:""});
db.<collection>.find({age:""});
// 4.3.4 查询集合中符合条件的第一个文档
db.<collection>.findOne({age:""});
// 查询所有结果的数量
db.<collection>.find({}).count();
// 4.4 修改
// 4.4.1 修改操作符
$set 修改属性值
$unset 删除属性值
db.<collection>.update({name:""}, {age:""}, {upsert:<boolean>, multi:<boolean>, writeConcern:<document>, collation:<document>}); // 默认情况下值更新一个值
// 4.4.1 同时修改多个符合条件的文档
db.<collection>.updateMany();0
// 4.4.2 修改一个符合条件的文档
db.<collection>.updateOne();
// 4.4.3 替换一个文档
db.<collection>.replaceOne();
// 4.5 删除
db.<collection>.deleteOne();
db.<collection>.deleteMany();
db.<collection>.remove(<query>, <justOne>); // 默认情况下会删除多个
2.1 文档之间的关系
2.1.1 1对1关系
夫妻 (一个丈夫 对应 一个妻子)
在MongoDB,可以通过内嵌文档的形式来体现出一对一的关系
db.wifeAndHusband.insert([{name:"黄蓉", husband:{name:"郭靖"}}]);
2.1.2 1对多关系
父母 - 孩子
用户 - 订单
文章 - 评论
也可以通过内嵌文档来映射一对多
// 方法1
db.artical.insert(title:"标题1", content:"content1", [{comment:"comment1"}, {comment:"comment2"}]);
// 方法2
db.users.insert([{username:"swk"},{username:"zbj"}]);
db.order.insert({list:["苹果","香蕉","大鸭梨"]}, user_id:ObjectId("xxxxxxx"));
var user_id = db.users.findOne({username:"swk"})._id;
db.order.find({user_id:user_id});
2.1.2 多对多关系
分类 - 商品 老师 - 学生
db.teachers.insert([{name:"洪七公"},{name:"黄药师"},{name:"龟仙人"}]);
db.students.insert([{name:"郭靖", teachers_id:[{ObjectId("xxx"), ObjectId("xxx")}]}]);
3.1 sort 和 投影
3.1.1 sort
查询文档时,默认情况时按照_id的值进行排列(升序)
sort()可以用来指定文档的排序的规则
db.emp.find({}).sort({sal:1}); // sal为字段名 1为升序 -1为降序
db.emp.find({}).sort({sal:1, empno:-1}); // sal升序排列 empno降序排列
limit skip sort 可以以任意顺序进行调用
3.1.2 投影
在查询时,可以在第二个参数的位置来设置查询结果的投影
db.emp.find({},{ename:1, _id:0, sal:1});
4. Mongoose
4.1 Mongoose简介
- 之前我们都是通过shell完成对数据库的各种操作的,在开发中大部分时候我们都需要通过程序来完成对数据库的操作。
- 而Mongoose就是一个让我们可以通过Node来操作MongoDB的模块。
- Mongoose时一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能。
- 在大多数情况下,它被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型转换等好处。
4.2 Mongoose的好处
- 可以为文档创建一个模式结构(Schema)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
4.3 新的对象
- mongoose中为我们提供了几个新的对象
- Schema(模式对象)
- Schema对象定义约束了数据库中的文档结构
- Model
- Model对象作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collection
- Document
- Document表示集合中的具体文档,相当于集合中的一个具体的文档
- Schema(模式对象)
4.4 如何使用Mongoose
// 1. 下载安装Mongoose
npm i mongoose --save
// 2. 在项目中引入mongoose
var mongoose = require("mongoose");
// 3. 连接MongoDB数据库
mongoose.connect('mongodb://数据库的ip地址:端口号/数据库名', {useMongoClient: true});
// 4. 监听MongoDB数据库的连接状态
// 在mongoose对象中,有一个属性叫做connection,该对象表示的就是数据库连接
// 通过建是该对象的状态,可以来监听数据库的连接与断开
mongoose.connection.once("open", function(){});
mongoose.connection.once("close", function(){});
// 5. 断开数据库连接(一般不需要调用)
mongoose.disconnection();
4.4.1 Schema
// 定义Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var blogSchema = new Schema({
title: String,
author: String,
body: String,
comments: [{body: String, date: Date}],
date: {type:Date, default: Date.now},
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
4.4.2 Model
// 通过Schema来创建Model
// Model代表的时数据库中的集合,通过Model才能对数据库进行操作
// mongoose.model(modelName, schema)
var BlogModel = mongoose.model("blog", blogSchema);
Blog.create({...}, function(err){
if(!err) {
console.log("插入成功");
}
});
/**
创建
Model.create(doc(s), [callback])
- 用来创建一个或多个文档并添加到数据库中
- 参数:
doc(s) 可以时一个文档对象,也可以时一个文档对象的数组
callback 当操作完成以后调用的回调函数
查询:
Model.find(conditions, [projection], [options], [callback])
- 查询所有符合条件的文档
Model.findById(id, [projection], [options], [callback])
- 根据文档的id属性查询文档
Model.findOne([conditions], [projection], [options], [callback])
- 查询符合条件的第一个文档
conditions 查询的条件
projection 投影 需要获取到的字段
两种方式
{name:1, _id:0}
"name -_id"
options 查询选项(skip limit)
callback 回调函数
修改
Model.update(conditions, doc, [options], [callback])
Model.updateMany(conditions, doc, [options], [callback])
Model.updateOne(conditions, doc, [options], [callback])
**/
4.3 Document
blog.save(function(err){
...
})
blog.findOne({}, function(err,doc) {
if(!err){
console.log(doc);
}
});