数据库之MongoDB基础篇

377 阅读5分钟

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中,数据库和集合都不需要手动创建
      • 当创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合

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表示集合中的具体文档,相当于集合中的一个具体的文档

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);
    }
});