了解
文档数据库MongoDB用于记录文档结构的数据,如JSON、XML结构的数据。一条文档就是一条记录(含数据和数据结构),一条记录里可以包含若干个键值对。键值对由键和值两部分组成,键又叫做字段。键值对的值可以是普通值,如字符串、整型等;也可以是其他值,如文档、数据及文档数据
{
GoodName: "战神", // 字符串类型值
Price: 44, // 实数类型值
AddedTime: 2016-3-1, // 日期类型值
Groups["书","it书"] // 数组类型值
{ISBN:"2214323423",Press:"电子工业"} //文档类型值
}
安装
1.下载MongoDB 3.4.4安装包到本机
2.建立安装路径,如D:\MongoDB\data。在D:\MongoDB\data路径下分别创建“\db”和"\log"子路径,
D:\MongoDB\data\db # 用于存放数据库文件
D:\MongoDB\data\log # 用于存放日志文件(mongod.log)
注意
必须要有data子文件路径,db和log子路径必须在data下面,不然安装完成后,执行MongoDB将会出错
bin路径下执行文件介绍
1.mongob.exe,是MongoDB最核心的服务器端数据库管理软件,不能暴露在公共网络上,主要实现服务器端数据库的数据处理、数据访问管理及其他后台管理,存在于每台数据库服务器上。数据库服务端
2.mongo.exe,客户端shell运行支持程序,为数据库系统管理提供了交互式操作数据库统一界面,也为系统开发人员测试数据库等操作提供了方便。Mongo实质是一个JavaScript代码交互式执行平台
3.mongos.exe,路由管理程序,用于MongoDB分片集群环境下的业务系统访问的路由管理
4.mongostat.exe,MongoDB运行状态监控工具,可以快速查看当前运行的mongod或mongos实例的状态
5.mongotop.exe,监控工具,可以根据时间持续对读写数据进行统计,默认1秒返回一次监控信息。
6.mongodump.exe,以人工执行方式,通过Mongod或Mongos,以二进制形式实现对数据库业务数据的导出备份。
7.mongorestore.exe,以人工执行方式,通过Mongod或Mongos,以二进制形式实现对备份数据的恢复,配合mongodump.exe一起使用
8.mongoexport.exe,在人工执行方式下,以JSON或CSV格式导出数据库数据
9.mongoimport.exe,在人工执行方式下,对mongoexport.exe导出的数据恢复到数据库系统之中。
- bsondump.exe,将BSON文件转换为可阅读的格式,如可以把Mongodump生成的输出文件转为JSON格式的可阅读文件
- mongofiles.exe,把任何数据类型的独立文件上传到MongoDB数据库中,以GridFS形式分块存储,并可以读取相应文件:MongoDB支持的各种编程语言的API接口都提供类似读写功能
- mongooplog.exe,以Oplog轮询的方式实现对远程服务器上的数据,同步到本地服务器上
- mongoperf.exe,用来测试磁盘IO性能的工具
开机自启/关闭服务
# 首先进入到mongodb安装目录的bin路径下
D:\Mongo\mongdb\bin>mongod --dbpath "d:\Mongo\mongdb\data\db" --logpath "d:\Mongo\mongdb\data\log\MongoDB.log" --install --serviceName "MongoDB"
D:\Mongo\mongdb\bin>net start MongoDB
MongoDB 服务正在启动 .
MongoDB 服务已经启动成功。
# 关闭服务
net stop MongoDB
文档值数据类型
数据类型 | 描述 | 举例 |
---|---|---|
null | 表示空值或者未定义的对象 | {"otherbook":null} |
布尔值 | 真或假 | {“allowing”: true} |
32位整数 | shell不支持该类型,默认会转换成64位浮点数,也可以使用NumberInt类 | {"number":NumberInt("3")} |
64位整数 | shell不支持该类型,默认会转换成64位浮点数,也可以使用NumberLong类 | {"longnumber":NumberLong("3")} |
64位浮点数 | shell中的数字就是这一种类型 | {"price":23.5} |
字符串 | utf-8字符串 | {"bookname":"it书籍"} |
符号 | shell不支持。它会将数据库中的符号类型的数据自动转换成字符串 | |
对象id | 文档的12字节的唯一id,保证一条文档记录的唯一性。可以在服务器端自动生成,也可以在代码端生成,允许程序员自行指定id值 | {"id":ObjectId()} |
日期 | 从标准纪元开始的毫秒数 | {"saledate": new Date()} |
正则表达式 | 文档中可以包含正则表达式,遵循JavaScript的语法 | {"foo":/foobar/i} |
代码 | 文档中可以包含JavaScript代码 | {"nodeprocess": function(){}} |
undefined | 未定义 | {"Explain": undefined} |
数组 | 值的集合或者列表 | {"books": ["C语言","go语言"]} |
内嵌文档 | JSON、XML等文档本身 | {bookname:"go语言",bookpice:33.2,adddate:2020-2-1,allow:true} |
数据库类型
1.admin数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin数据库中,那么该用户就自动继承了所有数据库的权限
2.local数据库:这个数据库永远不会被负责,可以用来存储本地单台服务器的任意集合
3.config数据库:当MongoDB使用分片模式时,config数据库在内部使用,用于保存分片的信息
4.test数据库:MongoDB安装后的默认数据库,可以用于数据库命令的各种操作,包括测试
mongodb数据库建立相关命令
创建自定义数据库名
use goodsdb
# 如果goodsdb数据库不存在,则新建立数据库,如果存在,则连接数据库,然后可以在该数据库上做各种命令操作
查看数据库
show dbs
// 对于刚刚建立的goodsdb数据库并没有显示出来,原因是goodsdb数据库里没有内容。
统计数据库信息
db.stats()
#
{
"db" : "goodsdb", # 数据库名
"collections" : 0, # 集合数量,刚刚安装为0
"views" : 0, #
"objects" : 0, # 文档对象的个数,所有集合的记录数之和
"avgObjSize" : 0, # 平均每个对象的大小,通过dataSize/objects得到
"dataSize" : 0, # 当前库所有集合的数据大小
"storageSize" : 0, # 磁盘存储大小
"numExtents" : 0, # 所有集合的扩展数据量统计数
"indexes" : 0, # 已建立索引数量
"indexSize" : 0, # 索引大小
"fileSize" : 0, # 文件大小
"ok" : 1
}
删除数据库
use goodsdb
db.dropDatabase()
# 显示删除成功
{ "ok" : 1 }
查看当前数据库下的集合名称
db.getCollectionNames()
查看数据库用户角色权限
show roles
增删改查
插入
1.插入一条简单文档
> use goodsdb
switched to db goodsdb
> db.goodsbaseinf.insert({name:"go语言",price:32})
WriteResult({ "nInserted" : 1 }) # 插入成功提示
> db.goodsbaseinf.find() # 显示集合内容
{ "_id" : ObjectId("62cc34c636d52f097f472808"), "name" : "go语言", "price" : 32 }
说明
1.insert命令,自动产生一个_id值
2.insert命令可以用过save命令代替。若给save命令指定
_id
值,则会更新默认的_id
值,如db.set1.save({_id:1002,x:"OK"})3.如果没有goodsbaseinf集合对象,则第一次insert时自动建立集合;若存在集合,则变成多条文档的集合
2.插入一条复杂文档
> db.goodsbaseinf.insert({name:"C语言",bookprice:33.2,adddate:2017-10-1,allow:true,baseinf:{ISBN:1882828121,pr
ess:"清华大学"},tags:["good","book","it","Program"]})
WriteResult({ "nInserted" : 1 })
> db.goodsbaseinf.find()
{ "_id" : ObjectId("62cc34c636d52f097f472808"), "name" : "go语言", "price" : 32 }
{ "_id" : ObjectId("62cc366c36d52f097f472809"), "name" : "C语言", "bookprice" : 33.2, "adddate" : 2006, "allow
" : true, "baseinf" : { "ISBN" : 1882828121, "press" : "清华大学" }, "tags" : [ "good", "book", "it", "Program
] }
3.插入多条文档
> db.goodsbaseinf.insert([{item:"小学教程",name:"小学一年级",price:12},{item:"初中教程",name:"初中一年级",price:15}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
注意
多条文档一次性插入,利用了insert的原子性事务特征,保证所有插入文档要么插入成功,要么不成功
4.用变量方式插入文档
document=({name:"go语言",price:32})
db.goodsbaseinf.insert(document)
5.有序插入多条文档
>db.goodsbaseinf.insert(
[
{
_id:10,item:"小学教程",name:"小学一年级",price:12
},
{
_id:11,item:"初中教程",name:"初中一年级",price:15
}
],
{ordered:true} # 有序插入设置
)
注意
如数据库中以有"_id:11"记录,那么执行记录时,将失败。不能重复插入。但是当有ordered时,当为true时,一条都不插入,为false时,除了出错记录外,其他记录继续插入
6.自定义写出错确认级别(含insert命令出错返回对象显示)
db.goodsbaseinf.insert(
{
_id:1,item:"小学教程",name:"小学一年级",price:12
},
{
writeConcern: { w: "majority",wtimeout:5000 }
}
)
7.插入单条
db.goodsbaseinf.insertOne(
{
item:"小学教程",name:"小学一年级",price:12
}
)
8.一次性插入多条文档
db.goodsbaseinf.insertMany(
[
{
item:"小学教程",name:"小学一年级",price:12
},
{
item:"初中教程",name:"初中一年级",price:15
}
]
)
查询
1.查询集合所有文档
db.goodsbaseinf.find()
db.goodsbaseinf.find().pretty() # 更好看的格式化输出
2.等价条件查询
db.goodsbaseinf.find(
{name:"go语言"}
)
3.不显示id及值,并指定显示值
# 显示name和price,不显示_id
db.goodsbaseinf.find(
{
name,"go语言"
},
{
name:1,price:1,_id:0 # 0或false不显示指定字段,1或true显示指定字段
}
)
4.嵌套文档查询
db.goodsbaseinf.find(
{
"baseinf.press":"清华大学"
}
)
5.数组查询
# 等价查询某一数组
db.goodsbaseinf.find(
{
tags:["good","book","it","Program"]
}
)
# 查询数组里的某一个值
db.goodsbaseinf.find(
{
tags:"good"
}
)
# 查询有4个元素的数组
db.goodsbaseinf.find(
{
tags:{$size:4}
}
)
6.查找null值字段,查找指定无值字段
db.goodsbaseinf.insert(
[
{_id:2222,toy:null},
{_id:1112}
]
)
# 查找null值字段
db.goodsbaseinf.find(
{_id:2222,toy:null}
)
# 查找的值不存在
db.goodsbaseinf.find(
{
_id:1112,toy:{$exists:false}
}
)
7.查找返回值游标操作
# 打印显示游标获取的集合
var showCursor=db.goodsbaseinf.find()
showCursor.forEach(printjson)
8.limit和skip方法查询
# 返回第一条文档
db.goodsbaseinf.find().limit(1)
# 显示第3条开始的文档记录
db.goodsbaseinf.find().skip(2)
9.带$in运算符的查询
# 用带$in运算符实现或(or)条件查找
# 查找_id等于12或ObjectId("3123566745123423421")的记录文档
db.goodsbaseinf.find(
{
_id:{
$in:[12,ObjectId("3123566745123423421")]
}
}
)
10.通过查询操作符来查询
操作符 | 格式 | 实例 | mysql类似语句 |
---|---|---|---|
小于 | { |
db.goodsbaseinf.find({price:{$lt:15}}) | where price<15 |
小于等于 | { |
db.goodsbaseinf.find({price:{$lte:15}}) | where price<=15 |
大于 | { |
db.goodsbaseinf.find({price:{$gt:15}}) | where price>15 |
大于等于 | { |
db.goodsbaseinf.find({price:{$gte:15}}) | where price>=15 |
不等于 | { |
db.goodsbaseinf.find({price:{$ne:15}}) | where price!=15 |
与(and) | {key1:value1,key2:value2,....} | db.goodsbaseinf.find({name:"xx",price:12}) | where name="xx" and price=12 |
或(or) | {$or:[{key1:value1},{key2:value2},...]} | db.goodsbaseinf.find({$or:[{name:"xx"},{price:12}]}) | where name="xx" or price=12 |
模糊匹配 | 查询以固定值结尾的 | db.goodsbaseinf.find({name:{$regex:/语文$/}}) | where name like "%语言" |
查询以固定值开头的 | db.goodsbaseinf.find({name:{$regex:/^C语言/}}) | where name like "C语言%" | |
查询以固定值的任意部分 | db.goodsbaseinf.find({name:{$regex:/C/}}) | where name like "%C%" |
11.区间条件查找
# 查询价格范围大于3小于33的值,可用于文档数值字段,也可以用于数组字段
db.goodsbaseinf.find(
{
price:{$gt:3,$lt:33}
}
)
更新
1.update命令参数
参数名称 | 说明 |
---|---|
query | update的查询条件,类似sql update查询where子句后面的查询条件 |
update | update的更新对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询set子句后面的更新内容 |
upsert | 可选,如果不存在update的记录,是否插入objNew;true为插入,默认是false,不插入 |
multi | 可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新 |
writeConcern | 可选,自定义写出错确认级别 |
collation | 可选,指定特定国家语言的更新归类规则 |
返回值:
更新成功,返回WriteResult({"nUpdated":n})对象
更新失败,返回结果中包含WriteResult.writeConcernError对象字段内容
2.修改一条简单文档
# 将购物单1修改为购物单2
use goodsdb
db.order.insert(
{
title:"商品购物单1",
amount:35,
}
)
# 改订单名称
db.order.update(
{title:"商品购物单1"},
{$set:{title:"商品购物单2"}}
)
# 修改数值
db.order.update(
{title:"商品购物单2"},
{$inc:{amount:5}} # $inc做加法运算,加5
)
# 修改titlss为title
db.order.update({_id:10,{$rename:{"titlss":"title"}}})
# 删除一个字段
db.order.update(
{
_id:10
},
{
$unset:{unit:"元"}
}
)
# 将$min给出的值与当前文档字段值进行比较,当给定值较小时则修改当前文档值为给定值
db.order.update(
{
_id:10
},
{
$min;{amount:50}
}
)
# 将$max给出的值与当前文档字段值进行比较,当给定值较大时则修改当前文档值为给定值
db.order.update(
{
_id:10
},
{
$max;{amount:50.5}
}
)
# 用ISODate更新当前文档时间字段的值
db.order.update(
{
_id:11
},
{
lasttime: ISODate("2019")
}
)
3.修改一条文档里的数组和嵌套文档
db.order.update(
{
_id:12
},
{
$set:{
# 采用下标的方式来指定要修改的对象
# 数组采用索引,从0开始
"detail.1":{name:"大米",price:40},
# 文档采用取key的方式
"overview.address": "天津市和平区"
}
}
)
4.多文档修改
# 修改所有面粉价格小于30的文档记录,把面粉价格改为40
db.order.update(
{
"detail.name":"面粉","detail.price":{$lte:30}
},
{
$set:{
"detail.1":{name:"面粉",price:40}
}
},
{
multi:true
}
)
5.增加文档字段
# update命令在特定情况下,可以增加文档的字段,甚至实现insert命令功能。这个特定条件是要修改的文档没有要修改的字段,而且update命令带upsert选项
db.order.update(
{
_id:10
},
{
$set:{"detail.0":{name:"西瓜",price:10},unit:"元"}
},
{
upsert:true
}
)
6.自定义写确认级别
# 当update命令在5秒内没有执行完成时,取消该命令操作,并返回错误值
db.order.update(
{
item:""
},
{
$set:{title:"测试",price:50}
},
{
multi:true,
writeconcern:{w: "majority", wtimeout:5000}
}
)
7.3个简化的修改命令
db.collection.updateOne()
db.collection.updateMany()
db.collection.replaceOne()
删除
1.删除参数说明
参数 | 说明 |
---|---|
必选,设置删除文档条件 | |
justOne: |
可选,false为默认值,删除符号条件的所有文档;true删除符合条件的一条文档 |
writeConcern: |
可选,自定义写出错确认级别 |
collation: |
可选,指定特定国家语言的删除归类规则 |
返回值:
删除成功,返回WriteResult({"nRemoved":n})对象。
删除失败,返回结果中会包含WriteResult.writeConcernError对象字段内容(跟writeConern配合使用)
2.删除一个集合里的所有文档记录
db.tests.remove({})
3.删除整个集合包括索引
db.tests.drop()
4.删除符合条件的所有文档记录
# 删除价格大于3的所有文档记录
db.tests.remove(
{
price:{$gt:3}
}
)
5.自定义写出错确认级别
# 删除价格小于3的所有文档记录,当时间超过5秒时,或者副本集大多数已完成该命令执行时,就中断该命令的执行,返回该命令的操作结果
db.tests.remove(
{
price:{$lt:3}
},
{
writeConern: {w: "majority", wtimeout:5000}
}
)
6.删除满足条件的单个文档记录
# 删除价格大于3的第一个文档记录
db.tests.remove(
{
price:{$gte:3}
},
{
justOne:true
}
)
7.删除含特殊语言符号的文档记录
db.tests.remove(
{
item:"cafe",price:{$lte:20}
},
{
justOne:true
},
{
cllation:{locale: "fr", strength:1}
}
)
索引
MongoDB数据库自动为集合_id建立唯一索引,可以避免重复插入同一_id的文档记录
单一字段(键)索引
语法:db.collection_name.createIndex({
命令说明:对一个集合文档的键建立索引,key为键名,n=1为升序,n=-1为降序
1.对单一键建立索引
db.books.createIndex(
{name:1}
)
2.嵌套文档单字段索引
db.books.insert(
{
name:"故事",
price:30,
tags:{press:"x出版社",call:"18222223321"}
}
)
db.books.createIndex({"tags.press":1})
字段唯一索引
语法:db.collection_name.createIndex({
命令说明:对一个或多个字段建立唯一索引。key为键名,n=1为升序,n=-1为降序
1.字段值唯一索引
db.books.createIndex({name:1}, {unique:true})
2.多字段索引
db.books.createIndex(
{
price:1,color:-1
}
)
3.多字段唯一索引
db.books.createIndex({name:1,price:1},{unique:true})
文本索引
语法:db.collection_name:createIndex({
命令说明:在集合里,为文本字段内容的文档建立文本索引
1.基本文档索引
db.books.createIndex({name:"text"})
2.指定权重文本索引
db.books.createIndex(
{
name:"text",
price:"text"
},
{
weigths:{name:10}, # 为name指定索引权重
name:"TextIndex" # 默认情况下,price权重为1
}
)
3.通配符文本索引
db.books.createIndex({"$**":"text"})
hash索引
语法:db.collection_name.createIndex({key:"hashed"})
命令说明:key为含有哈希值的键
1.建立哈希索引
db.collection.createIndex({_id:"hashed"})
hashed索引不支持多字段索引
hashed会把浮点数的小数部分自动去掉,所以对浮点数字段进行索引时,要注意该特殊情况
hashed不支持唯一索引
索引相关的其他方法
db.collection.dropIndex(index) # 移除集合指定的索引功能。index参数为指定需要删除的集合索引名,可用getIndexes()函数获取集合的所有索引名称
db.collection.dropIndexes() # 移除一个集合的所有索引功能
db.collection.getIndexes() # 返回一个指定集合的现有索引描述信息的文档数组
db.collection.reIndex() # 删除指定集合上所有索引,并重新构建所有现有索引,在具有大量数据集合的情况下,该操作将大量消耗服务器的运行资源,引起运行性能急剧下降等问题的发生。
db.collection.totalIndexSize() # 提供指定集合索引大小的报告信息