mongodb学习记录
MongoDB简介
1.MongoDB是为快速开发互联网web应用而设计的数据库系统
2.MongoDB的设计目标是极简,灵活,作为web应用栈的一部分
3.MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解就是MongoDB这个数据库中存的是各种各样的JSON.(BSON:相当于二进制的json)
MongoDB下载
稳定版是小版本:例如3.2 3.4 3.6
MongoDB对32位系统支持不加,3.2后没有再对32位系统的支持
安装过程
- 安装
- 配置环境变量,(将bin目录添加到环境变量)
- 找个位置 创建data文件夹,在data文件夹里创建db文件夹,作为数据库的目录
- 打开命令行,输入指令
mongod --dbpath 路径 --port 端口号
启动mongodb服务器,不要关闭该命令行窗口(路径是db的路径,端口号可以自己定,也可以不写--port 端口号
,这样会使用默认端口号27017,自己定的端口号最好四位,不要和其他的端口号冲突,最大不要超过65535) - 再打开一个cmd窗口,输入mongo,执行mongo启动客户端
数据库
数据库的服务器
服务器用来保存数据,mongod命令用来启动服务器
数据库的客户端
客户端用来操作服务器,对数据库进行增删改查的操作,mongo命令用来启动客户端
将MongoDB设置为系统服务
将MongoDB设置为系统服务,可以自动在后台启动,不需要每次手动启动(现在的版本可以直接安装成服务,安装版不用进行这样的配置,zip版本的需要进行配置)
-
在自己创建data目录下创建一个log文件夹
-
创建配置文件
在bin文件夹所在的目录添加一个配置文件mongod.cfg
-
打开配置文件,输入以下内容(缩进不能有错)
systemLog: destination: file path: 自己定义的log路径\mongod.log storage: dbPath: 自己定义的db路径
示例:
systemLog: destination: file path: G:\mongodb-windows-x86_64-5.0.6\data\log\mongod.log storage: dbPath: G:\mongodb-windows-x86_64-5.0.6\data\db
-
安装服务
用管理员方式运行命令行,在命令行执行以下命令:bin目录\mongod.exe --config "配置文件目录\mongod.cfg" --install
配置过环境变量的可以执行以下命令
mongod --config "配置文件目录\mongod.cfg" --install
示例:
mongod --config "G:\mongodb-windows-x86_64-5.0.6\mongodb-win32-x86_64-windows-5.0.6\mongod.cfg" --install
-
启动服务
可以通过net start MongoDB
和net stop MongoDB
来启动服务
可以通过mongod --remove
来删除服务
服务可以在任务管理器,服务里面进行查看
MongoDB基本操作
三个概念
- 数据库(database):数据库是一个仓库,在仓库中可以存放集合(collection)
- 集合(collection):一个集合类似于数组,在集合中可以存放文档(document)
- 文档(document):文档数据库中的最小单位,我们存储和操作的内容都是文档
注意:当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合
基本指令
- 查看数据库
show dbs
show dbs
show databases
- 创建/进入 指定数据库
use 数据库名
- 查看当前所处的数据库
db
- 查看集合,进入数据库后
show collections
数据库的CRUD操作(增删改查)
-
向数据库中插入文档
向集合中插入一个文档db.<collection>.insert(doc)
示例:向students集合中插入新的学生小A,年龄18,性别男db.students.insert({name:"小A",age:18,gender:"男"})
也可以插入多个学生(传入数组)
示例db.students.insert([ {name:"小B",age:19,gender:"男"}, {name:"小C",age:18,gender:"男"}, {name:"小D",age:17,gender:"女"}, {name:"小E",age:19,gender:"男"} ])
注意:如果没有指定_id属性,mongodb会自动添加一个_id属性,作为唯一标识,确保数据唯一性,如果我们指定_id,就不会自动添加,但是需要确保_id属性唯一
另外两种插入写法:
db.<collection>.insertOne(doc)
db.<collection>.insertMany([doc1,doc2,...])
-
查询文档
(1)查询集合中的所有文档db.<collection>.find()
find返回的是一个数组
示例:db.students.find()
可以在find中传递一个对象作为参数
示例:db.students.find({name:"小A"}) db.students.find({})/*查询所有文档*/
(2)查询集合中符合条件的第一个文档
db.<collection>.findOne()
findOne返回的是一个对象(3)获取查询结果的数量
db.<collection>.find().count()
-
修改文档
db.<collection>.update(查询条件,新对象)
注:update()默认情况会使用新对象替换旧对象
如果需要修改指定的属性,而不是替换,需要使用修改操作符,update默认只改一个
示例:/*修改一个文档*/ db.students.update( {name:"小A"}, {$set:{age:20}} ) /*修改多个文档*/ db.students.update( {age:19}, {$set:{age:21}}, {multi:true}/*update中加multi:true可以修改多个文档*/ )
修改操作符:
$set 可以用来修改文档的指定属性 $unset 可以用来删除文档的指定属性
db.<collection>.updateMany()
同时修改多个符合条件的文档
db.<collection>.updateOne()
修改一个符合条件的文档
db.<collection>.replaceOne()
替换一个符合条件的文档 -
删除文档
db.<collection>.remove()
可以根据条件来删除文档,传递条件的方式和find()一样,默认情况下可以删除符合条件的所有文档,如果只传递一个{}
会清空集合,但是清空时性能比较差
示例:db.students.remove({name:"小A"},true)/*只删一个*/
db.<collection>.deleteOne()
db.<collection>.deleteMany()
-
删除集合
db.<collection>.drop()
注意:删除所有集合相当于删除数据库
-
删除数据库
db.dropDatabase()
查询练习
1.查询numbers中num大于40小于50的文档
db.numbers.find({num:{$gt:40,$lt:50}});
2.查询numbers中大于50的文档
db.numbers.find({num:{$gt:50});
3.查看numbers集合中的第21条到30条数据
db.numbers.find().skip(20).limit(10);
skip()用于跳过指定数量的数据
limit()用于限制显示的数量
在开发中不会执行不带条件的查询
文档之间的关系
- 一对一(one to one)
在MongoDB,可以通过内嵌文档的形式来体现出一对一的关系,开发时一对一的情况较少
示例:(夫妻关系)db.wifeAndHusband.insert{[ { name:"黄蓉", husband:{ name:"郭靖" } } ]}
- 一对多(one to many)/多对一(many to one)
在MongoDB,一对多也可以通过内嵌文档的方式来解决,但是会比较复杂
通常会通过一个字段来建立两个数据集的联系var user_id = db.users.findOne({username:'小A'})._id; db.order.find({user_id:user_id});
- 多对多(many to many)
在MongoDB,多对多的关系通常可以通过数组来保存,在两个集合中同时进行更新,就可以实现多对多
比如老师的集合里面用数组存学生的id数组,学生的集合里面存老是的id数组,就可以实现老师学生多对多的关系
sort和投影
查询文档时,默认情况是按照_id的值进行排列(升序)
sort()可以用来指定文档的排序的规则,sort()需要传递一个对象来指定排序规则,1表示升序,-1表示降序
示例:
db.emp.fund({}).sort({sal:1,empno:-1});
limit skip sort可以以任意的顺序进行调用
在查询时,可以在第二个参数的位置来设置查询的结果 投影
示例:
db.emp.find({},{ename:1});
mongoose简介
Mongoose是一个让我们可以通过Node来操作MongoDB的模块。
Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装,并提供了更多的功能
在大多数情况下,它被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型转换等好处
mongoose的好处
- 可以为文档创建一个模式结构(Schema)
- 可以对模型中的对象/文档进行验证
- 数据可以通过类型转换转换为对象模型
- 可以使用中间件来应用业务逻辑挂钩
- 比Node原生的MongoDB驱动更容易
新的对象
mongoose中为我们提供了几个新的对象
- Schema(模式对象)
Schema对象定义约束了数据库中的文档结构 - Model
Model对象作为集合中的所有文档的表示,相当于MongoDB数据库中的集合collection - Document
Document表示集合中的具体文档,相当于集合中的一个具体的文档
mongoose使用
-
mongoose使用步骤
1.下载安装Mongoose npm i mongoose --save 2.在项目中引入mongoose var mongoose = require('mongoose') 3.连接MongoDB数据库 mongoose.connect('mongodb://数据库地址:端口号/数据库名',{useMongoClient:true}) 如果端口号是默认端口号(27017)则可以省略不写 4.断开数据库连接(一般不需要) mongoose.disconnect() - 监听MongoDB数据库的连接状态 - 在mongoose对象中,有一个属性叫connection,该对象表示的是数据库连接,通过监视该对象的状态,可以来监听数据库的连接与断开 //数据库连接的事件 mongoose.connection.once("open",function(){}); //数据库断开的事件 mongoose.connection.once("close",function(){});
注:MongoDB数据库,一般情况下,只需要连接一次,连接一次后,除非项目停止服务器关闭,否则连接一般不会断开
-
mongoose使用示例:
var mongoose = require("mongoose"); mongoose.connect("mongodn://127.0.0.1/test",{useMongoClient:true}) mongoose.connection.once("open",function(){ console.log("连接成功") }) //创建Schema(模式)对象 var Schema = mongoose.Schema var stuSchema = new Schema({ name:String, age:Number, gender:{ type:String, default:"female" } address:String }) //通过Schema来创建Model //Model代表的是数据库中的集合,通过Model才能对数据库进行操作 //mongoose.model(modelName,schema) //建立映射关系,students是集合,mongoose会自动将集合变成复数比如student会变成students var StuModel = mongoose.model("students",stuSchema) //向数据库中插入一个文档 StuModel.create({ name:"小A", age:18, gender:"male", address:"中国" },function(err){ if(!err){ console.log("插入成功") } })
Model的方法
-
有了Model,就可以对数据库进行增删改查
-
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 投影 - options 查询选项(skip limit) - callback 回调函数,查询结果会通过回调函数返回,回调函数必须传,如果不传回调函数压根不会查询
示例:
//-id表示不查询id,投影可以通过空格来隔开 StuModel.find({},"name age -id",function(err,docs){ if(!err){ console.log(docs) } }) //传统方式投影 StuModel.find({},{name:1,age:1,_id:0},function(err,docs){ if(!err){ console.log(docs) } }) //options 的使用 skip limit StuModel.find({},{name:1,age:1,_id:0},{skip:3,limit:1},function(err,docs){ if(!err){ console.log(docs) } }) /* 通过find()查询的结果,返回的对象,就是Document,文档对象 Document对象是Model的实例 可以通过instanceof来检查 console.log(doc instanceof StuModel) */
-
修改
1.Model.update(conditions,doc,[options],[callback]) 2.Model.updateMany(conditions,doc,[options],[callback]) 3.Model.updateOne(conditions,doc,[options],[callback]) 4.Model.replaceOne(conditions,doc,[options],[callback]) 参数: - conditions查询条件 - doc修改后的对象 - options配置参数 - callback回调函数
示例:
StuModel.update({name:"小A"},{$set:{age:15}},{multi:true},function(err){ if(!err){ console.log("修改成功") } })
-
删除(一般不用)
1.Model.remove(conditions,[callback]) 2.Model.deleteOne(conditions,[callback]) 3.Model.deleteMany(conditions,[callback])
-
Model.count(conditions,[callback])统计文档的数量
- callback两个参数 - err - count
document的常用方法
- 文档保存
Model#save([options],[fn])
示例:var stu = new StuModel({ name:"小B", age:17, gender:"male", address:"中国" }) stu.save(function(err){ if(!err){ console.log("保存成功") } })
- 修改对象
Model#update(update,[options],[callback])
示例:StuModel.findOne({},function(err,doc){ if(!err){ /*doc.update({$set:{age:28}},function(err){ console.log("修改成功") })*/ doc.age = 18; doc.save() } })
- 删除对象
Model#remove([callback])
- 其他方法示例
console.log(doc.get("age")) //也可以console.log(doc.age) doc.set("name","小C") //也可以doc.name="小C" doc.save() /* doc.toObject() 将Document对象转换为一个普通js对象后,所有的Document对象的方法或属性都不能使用了 */ doc = doc.toObject() delete doc.age//删除对象的某个属性,不是要从数据库中删除,所以要进行零时转化,这样的情况不多 console.log(doc)
mongoose的模块化
- 定义一个模块tools:
./tools/conn_mongo.js
,用来连接MongoDB数据库
可以在其他地方引入,就能连接数据库var mongoose = require("mongoose") mongoose.connect("mongodb://127.0.0.1/test") mongoose.connection.once("open",function(){ console.log("连接成功") })
require("./tools/conn_mongo")
- 定义一个模块models用来定义各类模型
示例./models/students
可以在其他地方引入/* 用来定义Students的模型 */ var mongoose = require("mongoose") var Schema = mongoose.Schema var stuSchema = new Schema({ name:String, age:Number, gender:{ type:String, default:"female" } address:String }) var StuModel = mongoose.model("students",stuSchema) module.exports = StuModel
require("./tools/conn_mongo") var Student = require("./models/students") //console.log(Student) Student.find({},function(err,docs){ if(!err){ console.log(docs) } })