数据库mongodb知识
1 安装与配置
- 下载地址:mongodb
- 按着步骤默认安装;拿到路径地址;安装文档
- 配置系统的环境变量;注:在window8系统中找到path后,点击编辑,会弹出变量框,在原地址后面用分号拼接上安装的路径,路径到bin文件夹下即可;配置环境变量链接
2 mongodb服务器与数据库
- mongodb服务器与数据库:
- 安装mongodb在一个地址中,这个地址就会创建一个bin文件夹,文件夹中有mongod.exe应用程序,这个文件夹就是服务器地址;
- 运行mongo命令,必须在bin文件夹下打开cmd,还可以设置环境变量,在path中用分号连接,bin文件夹的路径;这样设置后,在任何地方打开命令行,均可以使用mongo命令;
- 设置存储路径,即数据库的地址;就是文件增删改查的地址;通过命令
mongod --storageEngine mmapv1 --dbpath 数据库存储数据地址
;即存储样式为mmapv1样式,ns文件,在页面中可以看到数据库名称;配置完关闭窗口; - 设置存储路径后,该路径文件夹下就会生成一些文件,默认会生成三个数据库,admin,config,local;
- 开机:命令
mongod --dbpath 数据库存储数据地址
,指的是在该数据库中打开服务器;注:该窗口不关闭; - 连接服务器:新建一个cmd,输入mongo命令;连接打开的服务器,然后获取里面的数据库信息;
- 关机:将打开的服务器窗口关闭,即关闭了服务器;
- 总结:
- bin文件夹只有一个,代表服务器的路径;只有一个服务器;
- 数据库可以有多个,通过设置存储路径;即可创建多个数据库;
- 在哪个数据库中开机,可以获取该数据库中的信息;不同的数据库之间相互独立;
- mongdb的结构:
- mongdb => 多个数据库 => 每个数据库中有多个集合 => 每个集合中有多个document(文档数据格式:json)
3 mongodb常用命令
- 配置数据库的存储引擎,只需要配置一次;
- 命令:
mongod --storageEngine mmapv1 --dbpath 需要存放数据的数据库的目录地址
- 配置完,关闭窗口
- 命令:
- 开机:
mongod --dbpath 数据库的目录地址
- 创建mongo数据库的运行环境:
- 新建一个cmd
- 输入:mongo+回车;
- 清屏:cls;
- 查看某一个集合下的数据:
db.集合名.find()
;
4 关于mongodb的shell命令中的增删改查
4.1 数据库和集合的增删查
- 创建数据库
- 命令:
use Dataname
;注:创建数据库后必须在里面创建集合,否则,创建不成功;
- 命令:
- 删除数据库
- 命令:
db.dropDatabase()
;注:要删除哪个数据库,就进入哪个数据库中运行该命令;"db":查看在哪个数据库中;
- 命令:
- 创建集合
- 命令:
db.createCollection(name, options)
; - 也可以通过insert命令,向集合中插入数据;也能新建一个集合;插入数据和创建集合是同步的;
- 命令:
- 删除集合
- 命令:
db.xxx.drop()
;
- 命令:
- 查看所有数据库
- 命令:
show dbs
;
- 命令:
- 查看某数据库下的所有集合
- 命令:
show collections
或show tables
- 命令:
- 查看当前所在的数据库
- 命令:
db
;
- 命令:
4.2 集合下数据的增删改查
- 增加:
- 一条一条增加:
- 命令:
db.jihe.insert({})
;
- 命令:
- 批量导入增加:
- 命令:
mongoimport --db 数据库名字 --collection 集合 --drop --file 要导入的数据的地址
- 命令中的"要导入的数据地址"的路径要注意,鼠标右键属性中的路径地址,如:
E:\E盘\前端学习文件\教学视频学习\nodeClass\day7\data.json
; - 注:新开一个命令行,然后输入命令,导入数据库;
- 导入的数据为json格式的文件;文件中为josn格式的对象;每个对象之间不需要连接,报红是正常的;
- 命令:
- 一条一条增加:
- 查找:
- 查找所有数据:
db.jihe.find()
或db.jihe.find({})
;在后面添加一个pretty(),可以让信息呈现的漂亮些; - 查找指定的数据:
db.jihe.find({"name":"xiaoming"})
;- find可以找到所有符合条件的数据;
- findOne 可以找到一条符合条件数据;
- 花式查找数据:利用操作符,查找符合条件的数据;
- 操作符:
$lt
小于;$gt
大于- 代码:
db.mengsi.find({"age":{$gt:20}})
;指的是age大于20的所有数据; - 代码:
db.mengsi.find({"age":{$lt:40}})
;指的是age小于40的所有数据;
- 代码:
- 操作符:
- 查找的数据排序:
db.jihe.find().sort({"age":1})
- 1:正向排序;
- -1:反向排序;
- 查找总共有多少条数据:
db.jihe.find().count()
; - 查找数据分页显示;
- 设置每页显示n条数据;
- 命令:
db.jihe.find().limit(n)
;指的是每次只显示前n条数据;想查看后面的数据,需要设置跳过;
- 命令:
- 设置跳过多少条数据,查看下面的数据;
- 命令:
db.jihe.find().limit(每页显示的条数).skip(需要跳过的条数)
- eg:
db.jihe.find().limit(5).skip(5*2)
;指的是,显示跳过10条后的数据,即从第11条开始显示,显示5条;
- 设置每页显示n条数据;
- 查找所有数据:
- 修改(更新):
- 用新数据彻底覆盖旧数据,默认的都是修改一条;
- 命令:
db.mengsi.update(oldjson,newjson)
- eg:
db.mengsi.update({"name":"xiaoming"},{"name":"huahua"})
;指的是将里面的所有数据都覆盖,age数据不再存在;
- 命令:
- 只更改其中一些数据,不全覆盖,默认的都是修改一条;
- 命令:
db.mengsi.update(oldjson,{$set:newjson})
- eg:
db.mengsi.update({"name":"huanhuan"},{$set:{"name":"zhaomin"}})
- 命令:
- 修改多条数据,以上的命令均是默认修改一条;
- 命令:
db.mengsi.update(oldjson,{$set:newjson},{"multi":true})
- eg:
db.mengsi.update({"age":{$lt:40}},{$set:{"age":"18"}},{"multi":true})
;指的是,修改年龄小于40的所有数据,将其中age改为18,其他的数据不变;
- 命令:
- 用新数据彻底覆盖旧数据,默认的都是修改一条;
- 删除
- 删除数据库:
- 命令:
db.dropDatabase()
;在要删除的数据库下,运行该命令,则可以删除数据库;
- 命令:
- 删除集合:
- 命令:
db.test.drop()
;删除test集合;
- 命令:
- 删除集合中所有满足条件中的一条数据:
- 命令:
db.mengsi.remove({"age":18},{justOne:true})
,指的是删除一条;
- 命令:
- 删除集合中所有满足条件的数据:
- 命令:
db.mengsi.remove({"age":{$lt:40}})
;
- 命令:
- 删除集合中的所有数据:
- 命令:
db.mengsi.remove({})
;指的是删除集合下的所有数据,但集合还存在;
- 命令:
- 删除数据库:
5 mongodb与nodejs配合使用
- 先决条件
- mongodb与nodejs配合使用步骤
- 引入模块;
const MongoClient=require("mongodb").MongoClient;
- 设置数据库url;
const url="mongodb://localhost:27017";
- 连接数据库地址,获取数据库;
MongoClient.connect(url,{ useNewUrlParser: true },function(err,client))
- 设置
{ useNewUrlParser: true }
,防止报错; - 匿名函数中:err:错误信息;client:获取db
- 获取数据库:
const db=client.db(dbName);
;其中dbName为数据库的名称; - 获取该数据库下的集合:
const col=db.collection(collectionName);
;其中collectionName为该数据库下的集合名; - 通过col来进行对集合中的数据进行增删改查;
- 关闭与数据库的连接:
client.close()
;
- 设置
- 引入模块;
- 实例:连接数据库,获取集合下的所有数据;渲染到页面上显示;
- 代码:
//1.引入模块 const MongoClient=require("mongodb").MongoClient; //2.服务器本地域名; const url="mongodb://localhost:27017"; //3.连接服务器,获取数据库; MongoClient.connect(url,{ useNewUrlParser: true },function (err,client) { //设置{ useNewUrlParser: true },是为了不报错; if(err){ console.log("连接数据库失败"); return; } console.log("连接数据库成功"); //获取数据库,db,注:3.0以上版本和2.x以上版本有很大区别; //设置数据库名字 var dbName="guo"; const db=client.db(dbName); //获取该数据库下的集合名 const col=db.collection("mengsi"); col.find({}).toArray(function (err, items) {//将col集合下的数据转化为数组; if(err){ console.log("获取集合数据失败"); return; } console.log(items);//打印集合数据 client.close();//关闭数据库; }) });
6 封装数据库DAO方法
- 目的:
- 封装nodejs中mongodb的方法,便于调用使用;
- 在MVC中的models中创建db.js文件,用于封装mongodb的方法,通过exports导出;
- 在服务器中导入自定义模块db.js;引用方法;
- 思路:
- 在db.js中引入mongodb模块;然后连接数据库地址
- 创建mongoConnect(callback)函数,通过callback回调函数,导出client;
- mongoConnect函数的作用就是在需要用到db数据库的函数中,调用此函数,拿到client,进而拿到db,进而拿到col,通过方法对col集合下的数据进行操作;
- 封装方法,利用匿名函数设置形参,然后在服务器中引用的时候,导入实参;进而完成数据操作;通过回调函数callback将封装方法中的数据导出;
- 新建app.js文件,利用express创建服务器;引入自定义模块db.js;拿到封装的方法;
- 通过get请求不同的地址,来操作不同的函数,进而引用不同的col方法,对数据进行操作;
- 封装获取数据库和集合
- 数据库和集合参数,是在调用方法时传入的实参;
- 获取数据库:
var db=client.db(dbName)
- 获取数据下的集合:
var col=db.collection(collectionName)
- 封装时的方法
- 插入一条数据:
col.insertOne(json,callback)
; - 查找数据:
- 查找满足json条件的所有数据:
col.find(json).toArray(function(err,doc){..})
;通过toArray中的doc拿到数据以数组的形式获取; - 对查找到的数据进行排序:
col.find(json1).sort(json2).toArray(function (err,doc){})
;- json1:查找满足条件的json对象;
- json2:
- 取值:
{"age":1}
;指的是按age升序排列; - 取值:
{"age":-1}
;指的是按age降序排列; - 默认赋值为{},则乱序排列;
- 取值:
- 对查找的数据进行分页显示:
col.find(json1).limit(pageamount).skip(page*pageamount).toArray(function (err,doc){})
;- json1:查找满足条件的json对象;
- pageamount:指每页显示数据的个数;
- page:指第几页显示,实质就是跳过多少数据显示;
- page为0,则跳过0条,从第一条开始显示,总共显示pageamount条数据;
- page为1,则跳过1*pageamount条,则从pageamount+1条开始显示,总共显示pageamount条数据;
- page和pageamount赋值为Number类型;
- 查找满足json条件的所有数据:
- 修改(更新)数据:
- 修改多条:
col.updateMany(json1,json2,function (err,result){})
- json1:查找满足条件的json对象数据,待修改;
- json2:修改后的json对象数据;其中设置$set则只修改其中的一个属性,否则为全覆盖;
- 修改所有满足条件的数据;
- 修改多条:
- 删除数据:
- 删除多条:
col.deleteMany(json,function (err,result){})
- json:查找待删除的数据;
- 删除所有满足条件的数据;
- 删除多条:
- 查找满足条件的数据的总个数:
- 查找数据个数:
col.countDocuments(json,function (err,count){})
- json:查找数据的条件;
- count:拿到的是总个数,为Number类型;
- 注意:在响应页面时的res.send()中,不能放Number类型,所以需要通过toString()方法,将其转化为字符串;
- 查找数据个数:
- 插入一条数据:
- 封装后的代码:
//引入mongodb模块 const MongoClient=require("mongodb").MongoClient; //数据库地址 const url="mongodb://localhost:27017"; //连接数据库 function mongoConnect(callback) { MongoClient.connect(url,{ useNewUrlParser: true },function (err, client) { if(err){ console.log("连接数据库失败"); return; } console.log("连接数据库成功"); //将client通过callback回调函数传出; callback(client); }); } //1.在数据库中指定集合插入一条数据; //参数:数据库,集合, 插入数据,callback导出信息 exports.insertOne=function (dbname, collectionName, json, callback) { mongoConnect(function (client) { //获取数据库db,注:3.0以上版本获取数据库会有差异; var db=client.db(dbname); var col=db.collection(collectionName); col.insertOne(json,function (err, result) { callback(err,result); client.close();//关闭与数据库的连接 }) }) }; //2.查找数据库中集合下的数据 //参数:数据库 集合 待查找的数据 分页和排序参数 callback导出信息 //其中第四个分页和排序参数可传可不传; exports.find=function (dbname,collectionName,json1,json2,callback) { if(arguments.length===4){ //说明json2没有传;第四个参数传的是回调; callback=json2; json2={}; } var sort=json2.sort || {};//默认值为空对象,即乱序; var limit=Number(json2.limit) || 0;//默认值为0,必须为数字 var skip=Number(json2.skip) || 0;//默认跳过0; mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); //用toArray将获取的数据以数组的形式传出; col.find(json1).sort(sort).limit(limit).skip(skip*limit).toArray(function (err, doc) { callback(err,doc); client.close();//关闭与数据库的链接 }) }) }; //3 修改更新多条数据 //参数:数据库 集合 待修改数据 修改后的数据 callback导出信息 exports.updateMany=function (dbname, collectionName, json1, json2, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.updateMany(json1,json2,function (err, result) { callback(err,result); client.close(); }) }) }; //4 删除多条 //参数:数据库 集合 待删除 callback导出信息 exports.deleteMany=function (dbname, collectionName, json, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.deleteMany(json,function (err, result) { callback(err,result); client.close(); }) }) }; //5 获取集合下满足条件的总个数 //参数:数据库 集合 数据 callback导出信息 exports.count=function (dbname, collectionName, json, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.countDocuments(json,function (err, count) { callback(err,count); client.close(); }) }) };
7 使用封装后的方法
- 1.引入自定义模块
- 引入封装的js模块:
const db=require("./models/db")
;注:必须设置相对路径;
- 引入封装的js模块:
- 2.引用插入一条数据方法:insertOne
- 参数:1)数据库名 2)集合名 3)插入的数据json 4)callback回调函数导出结果信息;
- 代码:
db.insertOne("yanzheng","tiankong",{"name":"meili","age":5},function (err, result) { if(err){ console.log(err); return; } res.send(result); })
- 3.引用查找数据方法:find
- 参数:分为两种;
- 第一种:查找满足条件的所有数据;
- 四个参数:1)数据库名 2)集合名 3)查找的数据json 4)callback回调函数导出结果信息;
- 代码:
db.find("yanzheng","tiankong",{"age":5},function (err, result) { if(err){ console.log(err); return; } res.send(result);//result返回的是一个数组 })
- 第二种:查找数据并排序和分页;
- 五个参数:1)数据库名 2)集合名 3)查找的数据json 4)排序和分页(json对象) 5)callback回调函数导出结果信息;
- 排序和分页设置模板:
{"sort":{"age":-1},"limit":pageamount,"skip":page}
; - 其中排序sort设置{"age":1}为升序排列;page和pageamount为分页的页码和每页展示数据;
- 可以在地址栏中的设置
?page=xx&pageamount=xx
参数,通过req.query来获取page和pageamount值,再进行设置; - 代码:
formApp.get("/find",function (req, res) { //地址栏:http://localhost:8080/find?page=0&pageamount=10 //通过req.query来拿到地址中的存在; var pageamount=req.query.pageamount;//拿到的数据是string,在db.js中通过Number转化为数字,否则,会报错 var page=req.query.page; db.find("yanzheng","tiankong",{"age":5},{"sort":{"age":-1},"limit":pageamount,"skip":page},function (err, result) { if(err){ console.log(err); return; } res.send(result);//result返回的是一个数组 }) });
- 第一种:查找满足条件的所有数据;
- 参数:分为两种;
- 4.引用修改多条命令:updateMany
- 参数:1)数据库名 2)集合名 3)待修改的数据json 4)修改后的数据json 5)callback回调函数导出结果信息;
- 代码:
db.updateMany("yanzheng","tiankong",{"age":5},{$set:{"name":"guobin"}},function (err, result) { if(err){ console.log(err); return; } res.send(result); })
- 5.引用删除多条命令:deleteMany
- 参数:1)数据库名 2)集合名 3)待删除的数据json 4)callback回调函数导出结果
- 代码:
db.deleteMany("yanzheng","tiankong",{"age":5},function (err, result) { if(err){ console.log(err); return; } res.send(result); })
- 6.引用查找满足条件的数据总个数:count
- 参数:1)数据库名 2)集合名 3)查找满足条件的数据json 4)callback回调函数导出结果
- 代码:
db.count("yanzheng","tiankong",{"age":5},function (err, result) { if(err) { console.log(err); return; } res.send(result.toString());//send中不能放数字,拿到的result为数字; })
- 服务器中请求与方法的使用;
- 代码:
const express=require("express"); //引入自定义模块,需要设置相对路径; const db=require("./models/db"); const formApp=express(); //1. 发送请求,插入一条数据 //get:"/addOne" => 向数据库yanzheng下的tiankong集合中插入一条{"name":"meili","age":5}的数据; formApp.get("/addOne",function (req, res) { db.insertOne("yanzheng","tiankong",{"name":"meili","age":5},function (err, result) { if(err){ console.log(err); return; } res.send(result); }) }); //2. 发送"/find"请求,查找数据 //get:"/find" => 查找yanzheng数据库中tiankong集合下数据为{"age":5}的所有数据,进行降序排列,显示几条和跳过几条; formApp.get("/find",function (req, res) { //地址栏:http://localhost:8080/find?page=0&pageamount=10 //通过req.query来拿到地址中的存在; var pageamount=req.query.pageamount;//拿到的数据是string,在db.js中通过Number转化为数字,否则,会报错 var page=req.query.page; //传五个实参:1)数据库 2)集合名 3)查找的数据(json对象) 4)分页和排序(json对象) 5)callback //其中第四个分页和排序参数可传可不传; //第四个分页和排序参数模板:{"sort":{"age":-1},"limit":pageamount,"skip":page} db.find("yanzheng","tiankong",{"age":5},{"sort":{"age":-1},"limit":pageamount,"skip":page},function (err, result) { if(err){ console.log(err); return; } res.send(result);//result返回的是一个数组 }) }); //3. 发送请求"/update",更改数据 //get:"/update" => 修改yanzheng数据库下tiankong集合中的满足{"age":5}条件的所有数据中的name值修改为guobin; formApp.get("/update",function (req, res) { db.updateMany("yanzheng","tiankong",{"age":5},{$set:{"name":"guobin"}},function (err, result) { if(err){ console.log(err); return; } res.send(result); }) }); //4. 发送请求"/delete",删除数据 //get:"/delete" => 删除yanzheng数据库下tiankong集合下的满足条件的所有数据; formApp.get("/delete",function (req, res) { db.deleteMany("yanzheng","tiankong",{"age":5},function (err, result) { if(err){ console.log(err); return; } res.send(result); }) }); //5. 发送请求"/count",获取集合下满足情况的所有数据 //get:"/count" => 获取yanzheng数据库下tiankong集合下满足条件的数据总个数; formApp.get("/count",function (req, res) { db.count("yanzheng","tiankong",{"age":5},function (err, result) { if(err) { console.log(err); return; } res.send(result.toString());//send中不能放数字,拿到的result为数字; }) }); //监听端口号 formApp.listen(8080);
8 数据库方法的封装精化
- 根据上面的封装中;将数据库地址和数据库名字,单独通过setting.js文件进行设置;然后引入到db.js文件中,这样就可以在setting中设置数据库地址和数据库名字,简单方便;
- 改进后的代码:
- 设置数据库地址和数据库名字的setting.js文件代码:
//设置数据库地址 exports.url="mongodb://localhost:27017"; //设置数据库名称 exports.dbName="login";
- 封装的mongodb.js文件代码:
//引入mongodb模块 const MongoClient=require("mongodb").MongoClient; //引入自定义模块setting const setting=require("../setting-liuyan"); //数据库地址 const url=setting.url; //数据库名 const dbname=setting.dbName; //连接数据库 function mongoConnect(callback) { MongoClient.connect(url,{ useNewUrlParser: true },function (err, client) { if(err){ console.log("连接数据库失败"); return; } //将client通过callback回调函数传出; callback(client); }); } //1.在数据库中指定集合插入一条数据; //参数:集合, 插入数据,callback导出信息 exports.insertOne=function (collectionName, json, callback) { mongoConnect(function (client) { //获取数据库db,注:3.0以上版本获取数据库会有差异; var db=client.db(dbname); var col=db.collection(collectionName); col.insertOne(json,function (err, result) { callback(err,result); client.close();//关闭与数据库的连接 }) }) }; //2.查找数据库中集合下的数据 //参数:集合 待查找的数据 分页和排序参数 callback导出信息 //其中第三个分页和排序参数可传可不传; exports.find=function (collectionName,json1,json2,callback) { if(arguments.length===3){ //说明json2没有传;第三个参数传的是回调; callback=json2; json2={}; } var sort=json2.sort || {};//默认值为空对象,即乱序; var limit=Number(json2.pageamount) || 0;//默认值为0,必须为数字 var skip=Number(json2.page) || 0;//默认跳过0; mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); //用toArray将获取的数据以数组的形式传出; col.find(json1).sort(sort).limit(limit).skip(skip*limit).toArray(function (err, doc) { callback(err,doc); client.close();//关闭与数据库的链接 }) }) }; //3 修改更新数据 //参数:集合 待修改数据 修改后的数据 callback导出信息 exports.updateMany=function (collectionName, json1, json2, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.updateMany(json1,json2,function (err, result) { callback(err,result); client.close(); }) }) }; //4 删除 //参数:集合 待删除 callback导出信息 exports.deleteMany=function (collectionName, json, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.deleteMany(json,function (err, result) { callback(err,result); client.close(); }) }) }; //5 获取集合下满足条件的总个数 //参数:集合 数据 callback导出信息 exports.count=function (collectionName, json, callback) { mongoConnect(function (client) { var db=client.db(dbname); var col=db.collection(collectionName); col.countDocuments(json,function (err, count) { callback(err,count); client.close(); }) }) };