mongodb作为nosql中排名第一的数据库,近年来使用的人数越来越多,作为开发人员,非常有必要了解下mongodb数据库。下面就给大家介绍下mongodb数据库的基本知识,有不对的地方欢迎指正,QQ:1416759661。 另外也欢迎大家加QQ群7835003公共讨论.
如果感觉这篇文章理解有难度,我们还有相关的视频教程http://www.yyjcw.com/list.html
1 基本概念
1.1 什么是数据库
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据库技术得到了更加快速的发展,应用得更加广泛。主要用它进行管理各种系统的数据,作为科学研究和决策的重要技术手段。
1.2 常见的数据库
关系型数据库:Access mySql SqlServer oracle db2等。
非关系型数据库: MongoDB,Redis,HBase,CouchDB,SQLite等。
1.3 NoSQL简介
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是sql”,泛指非关系型的数据库。
随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
1.4 MongoDB简介
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是非关系型数据库当中功能最丰富,最像关系型数据库的。
2 准备工作
2.1 MongoDB下载与安装
MongoDB官网地址:
MongoDB下载地址:
https://www.mongodb.com/download-center#community
MongoDB for Windows 64-bit 适合 64 位的 Windows Server 2008 R2, Windows 7 , 及最新版本的 Window 系统。
MongoDB for Windows 32-bit 适合 32 位的 Window 系统及最新的 Windows Vista。 32 位系统上 MongoDB 的数据库最大为 2GB。
选择适合自己系统的版本进行下载:
根据你的系统下载 32 位或 64 位的 .msi 文件,下载后双击该文件,按操作提示安装即可。
2.2 mongochef安装
mongochef可以提高你使用MongoDB的幸福指数,他是MongoDB的可视化界面管理工具。
2.3 设置环境变量
Win7下设置环境变量:QQ 1416759661
第一步:我的电脑上点击右键,选择属性
第二步:找到并打开“高级系统配置”。
在接下来的页面中点击“高级系统配置”,打开“系统属性”窗口。
第三步:找到“环境变量”按钮并点击。
第四部:在环境变量窗口中一般有两个变量,一个是你当前所使用的用户独有的环境变量,另一个是所有用户都可以访问的系统变量。其实如果在你的电脑上你只使用一个用户的话,那么不管你修改的用户的环境变量还是系统变量,效果都是一样的。为了以防未来会新建其他用户,那么我建议你修改系统变量而不是某个用户独有的环境变量。
在变量值最后加上分号 ;C:\Program Files\MongoDB\Server\3.2\bin
然后保存。
2.4 创建文件夹
我们之前安装的是数据管理软件,通过数据库管理软件可以建立很多个数据库文件,我们打算把新建的数据库文件放哪里呢?需要指定一个位置。
Mongodb 数据库管理软件与数据库文件的关系就像office软件与word文档的关系。
1、在d盘建立一个文件夹mongodb,并且建立子目录db和log.
d:\mongodb\db、d:\mongodb\log, 分别用来存放数据库文件和数据库日志文件.
2、把mongodb文件夹的只读属性去掉。
2.5 启动MongoDB将其安装为windows服务
以管理员身份运行cmd.exe,进入dos命令界面,执行下列命令
mongod --dbpath "d:\mongodb\db" --logpath "d:\mongodb\log\MongoDB.log" –logappend --install --serviceName "MongoDB"
mongod.exe --remove --serviceName "MongoDB"
当mongod.exe被关闭时,mongo.exe 就无法连接到数据库了,因此每次想使用mongodb数据库都要开启mongod.exe程序,所以比较麻烦,此时我们可以将MongoDB安装为windows服务
以管理员身份运行cmd,进入bin文件夹,执行下列命令
mongod --dbpath "d:\mongodb\db" --logpath "d:\mongodb\log\MongoDB.log" --install --serviceName "MongoDB"
这里MongoDB.log就是开始建立的日志文件,--serviceName "MongoDB" 服务名为MongoDB
接着启动mongodb服务
> NET START MongoDB
打开任务管理器,可以看到进程已经启动。
测试连接
> mongo
2.6 关闭服务
先 ctrl+c
关闭服务:net stop MongoDB
3 MongoDB基础应用
3.1 常用的命令
> Help 查看帮助
显示数据库列表 > show dbs
创建数据库 > use dbname
如果数据库不存在,则创建数据库dbname,否则切换到指定数据库dbname。创建的数据库并不在数据库的列表中,要显示它,我们需要向数据库dbname插入一些数据
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
显示数据库中的集合 show collections
3.2 增加数据
db.web.save({"name":"老李"}) 创建了名为web的集合,并新增了一条{"name":"老李"} 的数据
db.web.insert({"name":"ghost", "age":10}) 在web集合中插入一条新数据,如果没有web这个集合,mongodb会自动创建
save()和insert()也存在着些许区别:若新增的数据主键已经存在,insert()会不做操作并提示错误,而save() 则更改原来的内容为新内容。
_id是主键,主键是每条数据的唯一标识,不能重复,就像身份证是每个人唯一的编号一样。
存在数据:{ _id : ObjectId("57e8d34b4764fb71d0a89caa"), " name " : " 老李"} ,_id是主键
insert({ _id : ObjectId("57e8d34b4764fb71d0a89caa"), " name " : " 老王 " }) 会提示错误
save(ObjectId("57e8d34b4764fb71d0a89caa"), " name " : " 老王 " }) 会把“老李”改为“ 老王”,有update的作用。
3.3 删除数据
1、删除文档
2、删除集合
3、删除数据库
- db.users.remove({}) 删除users集合下所有数据
- db.users.remove({"name": "lecaf"}) 删除users集合下name=”lecaf”的数据
- db.users.drop()或db.runCommand({"drop","users"}) 删除集合users
- db.runCommand({"dropDatabase": 1}) 删除当前数据库,注意此处的1没加双引号。
- db.users.find() 查找users集合中所有数据
- db.users.findOne() 查找users集合中的第一条数据
- db.web.update({"name":"a1"}, {"sex":1}) 修改name=a1的数据为sex=1,第一个参数是查找条件,第二个参数是修改内容,主键不能修改,如图
3.4 查找数据
3.5 修改数据
3.6 MongoDB高级应用
3.6.1 条件查找
学习用命令的意义在于:我们做系统的时候,后端人员需要给前端开发人员提供数据,如果后端人员用可视化工具,只是他自己眼睛能看到,但是如果要把这些数据提供给前端,他需要用代码去查数据库,把查询的结果返回给前端。
为此:老师给大家整理了下以下这些常见的查询例子,如果你以后忘记了,就翻出来看看。
提前做了一个歌手的json数据,我们可以把他导入到数据库,练习查找命令。
语法1:db.collection.find({ "key" : value }) 查找key=value的数据.
例1:查找女歌星。
思路:查找sex=”女”的歌星。
具体命令:
语法2: db.collection.find({ "key" : { $gt: value } }) key > value
例2:查找年龄大于53的歌星。
语法3:db.collection.find({ "key" : { $lt: value } }) key < value
例3:查询年龄小于35岁的歌星。
语法4:db.collection.find({ "key" : { $gte: value } }) key >= value
例4:查询成绩大于等于95的歌星。
语法5:db.collection.find({ "key" : { $lte: value } }) key <= value
例5:查询年龄在小于等于32岁的歌星。
语法6:db.collection.find({ "key" : { $gt: value1 , $lt: value2 } }) value1 < key <value2
例6:查找年龄在30-40岁之间的歌星。
语法7:db.collection.find({ "key" : { $ne: value } }) key <> value
例7:查询外国歌手。
分析:条件为 country不等于”中国”
语法8:db.collection.find({ "key" : { $mod : [ 10 , 1 ] } }) 取模运算,条件相当于key % 10 == 1 即key除以10余数为1的
例8:查询成绩为5 、15、25、。。。。95的歌星。
语法9:db.collection.find({ "key" : { $in: [ 1, 2, 3 ] } }) 属于,条件相当于key等于[ 1, 2, 3 ]中任何一个.
例9:查询序号(num)为3或者6或者9的歌星。
语法10:db.collection.find({ "key" : { $nin: [ 1, 2, 3 ] } }) 不属于,条件相当于key的值不属于[ 1, 2, 3 ]中任何一个。
例10:查询国籍不为美国和韩国的歌手。
语法11:db.collection.find({ "key" : { $size: 1 } }) $size 数量、尺寸,条件相当于key对应的值的数量是1(值必须是数组)
这个有点难理解,通过例子理解容易些:
每个歌星都有代表作,并且代表作是数组。
例11:查询有3个代表作品的歌手。
语法12:db.collection.find({ "key" : { $exists : true|false } })
$exists 字段存在,true返回存在字段key的数据,false返回不存在字段key的数据
例12-1:查询包含tel字段的数据。
之前的数据字段都是一样的,此时插入一条数据{"name":"test","tel":"15388889999"}
然后查询:
例12-2 :查询不包含tel字段的数据
语法13:db.collection.find({ $or : [{a : 1}, {b : 2} ] })
符合两个条件中任意一个的数据。$or语法表示或的意思。 (注意:MongoDB 1.5.3后版本可用),符合条件a=1的或者符合条件b=2的数据都会查询出来。
例13:某个娱乐公司15个人,资料都在数据库里面,某个活动必须要刘德华参加,另外需要团队的全部女歌手配合演出,领导安排你帮忙打印歌手的资料。
db.collection.find({ "key.subkey" :value }) 内嵌对象中的值匹配,注意:"key.subkey"必须加引号。
例14:插入一条测试数据
db.singer.insert({"name":"test2",score:{"yy":80,"sx":79,"wy":95}})
此数据的score对应的值是一个对象。
例14:查询语文成绩为80的同学。
3.6.2 排序
db.collection.find().sort({ "key1" : -1 ,"key2" : 1 }) 这里的1代表升序,-1代表降序
例1:对所有歌星安年龄排序。
例2:对所有歌星先按年龄降序排列,再按num字段降序排列。
注意:json数据里面的num是String类型的。
3.6.3 索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
例如:我们查询李宇春的时候 db.singer.find({"name":"李宇春"})
如果没有对name 字段建立索引,数据库在查询的时候会扫描所有的数据,如果数据量小的时候,感觉不出来速度慢,当数据越来越多的时候,就会越来越慢。
这个时候如果给name 建立一个索引,查询速度就会加快。
MongoDB使用 ensureIndex() 方法来创建索引。
ensureIndex()方法基本语法格式如下所示:
>db.COLLECTION_NAME.ensureIndex({KEY:1})
对name 字段建立一个索引如下:
可视化工具里面可以看到刚创建的索引:
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
实例
>db.col.ensureIndex({"title":1})>
ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
> db.col.ensureIndex({"title":1,"description":-1})
3.6.4 其他
db.collection.find().limit(5) 控制返回结果数量,如果参数是0,则当作没有约束,limit()将不起作用
db.collection.find().skip(5) 控制返回结果跳过多少数量,如果参数是0,则当作没有约束,skip()将不起作用,或者说跳过了0条
db.collection.find().skip(5).limit(5) 可用来做分页,跳过5条数据再取5条数据
db.collection.find().count(true) count()返回结果集的条数
db.collection.find().skip(5).limit(5).count(true) 在加入skip()和limit()这两个操作时,要获得实际返回的结果数,需要一个参数true,否则返回的是符合查询条件的结果总数
模糊查询:
db.collection.find({"name":/ab/})
以上是常见的查询,如果工作中遇到更加复杂的需求,可以通过查文档来解决。
3.7 使用可视化工具
4 Mongoose
4.1 Mongoose简介
Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用。
官方文档:https://www.npmjs.com/package/mongoose
前提:安装nodejs和mongodb
4.2 Mongoose的操作流程
4.2.1 安装mongoose
npm install mongoose
4.2.2 连接数据库
使用mongoose连接数据库的前提条件是:
1、mongo数据库已经运行。
2、已经安装了mongoose包
var mongoose = require("mongoose");
mongoose.Promise = global.Promise;//配置mongoose的Promise。
// 连接字符串格式为mongodb://主机/数据库名
mongoose.connect('mongodb://localhost/student');
上面这句的意思是连接到本地的mongodb的student数据库。
扩展:
mongoose.Promise = global.Promise;
// 连接本地mongodb ,本机的ip 127.0.0.1,端口:27017 数据库:student
mongoose.connect("mongodb://127.0.0.1:27017/student",function(err){
if(!err){//如果连接成功,则打印出connected to Mongodb
console.log("connected to Mongodb");
}else{
throw err;//如果连接失败,则抛出异常
}
});
4.2.3 新增数据
先讲解一个概念 Schema:
它可以理解为数据库模型骨架,可以看作工厂中模具一样,好比一个茶杯,喝水是茶杯最终的功能,茶杯本身就像是Model,那么茶杯的批量生产是需要靠工厂的模具成型的。Schema不仅定义了文档结构和使用性能,还可以有扩展插件、实例方法、静态方法、复合索引、文档生命周期钩子。
存储数据步骤:定义Schema- (模式)>创建model-(模型)>实例化方法。
var Schema = mongoose.Schema;
//通过Schema创建一个模式NewsSchema
var studentSchema = new Schema({
name: String,
age: String
});
studentSchema 类型有哪些:
//通过模式studentSchema 创建一个模型studentModel
var studentModel = mongoose.model("students",studentSchema );
var studentQueryModel= mongoose.model("students");//用于查询的模型
//通过模型studentModel 写入数据
var instance1 = new studentModel ();
instance1.name="yyjcw";
instance1.age="18";
//通过save方法保存
instance1.save(function(err){
if (err) {
console.log('保存失败');
return;
}
});
4.2.4 删除数据
思路:
1、删除数据首先要知道删除哪一条信息,需要知道信息的id.
2、把对应id的数据查询出来,执行remove方法
假如我们要删除id=”57e24521a755e1154039a403”的数据。
var id=”57e24521a755e1154039a403”;
studentQueryModel.findById(id,function(err,doc){
if(!doc){
return next(new NotFound("Doc not found"))
}else{
doc.remove(function(){
console.log('删除成功');
})
}
});
4.2.5 修改数据
修改数据的思路:先把对应id的数据查询出来,对需要修改的字段重新赋值,然后执行save方法保存。
假如我们要修改id=”57e24521a755e1154039a403”的数据。
var id=”57e24521a755e1154039a403”;
studentQueryModel.findById(id,function(err,doc){
//console.log(doc);
doc.name="xiaoyyjcw" ;//把name修改为xiaoyyjcw
doc.save(function(err){
if(!err){
console.log('修改成功');
}else{
throw err;
}
});
});
4.2.6 查询数据
下面find第一个参数{}里面为空,表示查询所有的数据:
docs表示查询的结果集合。
studentQueryModel.find({},function(err,docs){
console.log(docs);
});