mongoDB简介
MongoDB是用C++语言编写的非关系型数据库。特点是高性能、易部署、易使用,存储数据十分方便,主要特性有:
面向集合存储,易于存储对象类型的数据
模式自由
支持动态查询
支持完全索引,包含内部对象
支持复制和故障恢复
使用高效的二进制数据存储,包括大型对象
文件存储格式为BSON(一种JSON的扩展)
mongoDB 概念
1.database 数据库
多个集合逻辑上组织在一起,就是数据库。
数据库命名规范:
- 不能是空字符串("")。
- 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
- 应全部小写。
- 最多64字节。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
2. collection 集合
多个文档组成一个集合,相当于关系数据库的表。
所有存储在集合中的数据都是 BSON 格式,BSON 是类 JSON 的一种二进制形式的存储格式,简称 Binary JSON。
集合名命名规范:
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
-
用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
3. document 文档
MongoDB 将数据存储为一个文档,数据结构由键值对组成。
MongoDB 文档是一组键值对(即BSON,二进制的 JSON),类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)。
需要注意的是:
- 文档中的键值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
4.mongoDB - 数据类型
ObjectId:主键,一种特殊而且非常重要的类型,每个文档都会默认配置这个属性,属性名为_id,除非自己定义,方可覆盖
mongoDB命令
1.创建数据存储目录
mongoDB将目录存储在db目录下,需手动创建。
/Users/mrotaku/Desktop
2.开启mongoDB的服务器
dbpath指定数据的存放位置,port指定端口号,关闭服务:ctrl + c
mongod --dbpath=/Users/mrotaku/Desktop/nosql --port 27017
3.数据库常用命令
连接指定mongoDB
ctrl+c
关闭连接
mongo localhost:27017
查看当前数据库
db
查看所有数据库
mongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
show dbs
连接指定数据库
如果数据库不存在,则创建数据库,否则切换到指定数据库。
use db_name
查看服务器状态
db.serverStatus()
查看数据库统计信息
db.stats()
删除数据库
db.dropDatabase()
查看数据库中所有集合
show collections
或
show tables
清空集合
删除里面的文档,但集合还在
db.db_name.romve({})
删除集合
db.db_name.drop()
查看集合详细信息
db.db_name.find(key,value).explain("allPlansExecution")
mongoDB的增删查改
1.添加
mongoDB使用insert()或者save()的方法向集合中插入数据
如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。
insert() 或 save() 方法都可以向collection里插入数据,两者区别:
如果不指定 _id 字段,save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
使用save函数,如果原来的对象不存在,那他们都可以向collection里插入数据,如果已经存在,save会调用update更新里面的记录,而insert则会忽略操作
insert可以一次性插入一个列表,而不用遍历,效率高, save则需要遍历列表,一个个插入。
例如向col集合中插入一条数据:
db.col_1.insert({
name:'zhangsan',
age:23,
phone:1877768121
})
第二种方式:
document = ({
name:'lisi',
age:19,
phone:15633577595
});
db.col_1.insert(document)
2.更新
mongoDB使用update语句更新集合中的文档
db.collection.update(criteria,objNew,upsert,multi)
参数说明:
criteria:用于设置查询条件的对象
objNew:用于设置更新内容的对象
upsert:如果记录已经存在,更新它,否则新增一个记录,取值为0或1
multi:如果有多个符合条件的记录,是否全部更新,取值为0或1
注意:默认情况下,只会更新第一个符合条件的记录
一般情况下后两个参数分别为0,1 ,即:
db.collection.update(criteria,objNew,0,1)
$set 操作符为部分更新操作符,只更新 $set 之后的数据,而不是覆盖之前的数据
-->将用户名称为"zhangsan"用户的年龄更改为18
db.col_1.update({name:'zhangsan'},{$set:{age:18}})
以上语句只会修改第一条发现的文档,如果要修改多条相同的文档,则需要设置 multi 参数为 true。
db.col_1.update({name:'zhangsan'},{$set:{age:18}},{multi:true})
更新集合中的文档,使用 $inc 将集合中name为user1的age加1,其它键不变, $inc表示使某个键值加减指定的数值
db.col_1.update({name:'zhangsan'},{$inc:{age:1}})
3.删除
remove() 函数是用来删除集合中的数据
在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。
删除集合中所有文档
db.col_1.romve({})
移除集合中查询到的数据的第一条
db.col_1.romve({name:'zhangsan'},1)
4.查询
db.col_name.find(query, projection)
- query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
find()方法,查询返回集合中的所有文档
db.col_1.find()
findOne(),查询返回集合中的第一个文档
db.col_1.findOne()
格式化输出
db.col_1.find().pretty()
查询文档的个数
db.col_1.find().count()
跳过指定数量的数据
db.col_1.find().skip()
分页查询文档
db.col_1.find().limit();
想要读取从 10 条记录后 100 条记录,相当于 sql 中limit (10,100)。
db.col_1.find().skip(10).limit(100)
排序
sort()方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而-1是用于降序排列。
db.col_1.find().sort({key:1});
4.查询+where语句
如果你想获取"col"集合中 "likes" 大于100,小于 200 的数据,你可以使用以下命令:
db.col_1.find({likes : {$lt :200, $gt : 100}})
// 类似于SQL语句:
Select * from col where likes>100 AND likes<200;
条件操作符 | 中文 | 全英文 |
---|---|---|
$gt | 大于 | greater than |
$gte | 大于等于 | greater than equal |
$lt | 小于 | less than |
$lte | 小于等于 | less than equal |
$ne | 不等于 | not equal |
5.AND 条件
find() 方法可以传入多个键(key),每个键(key)以逗号隔开,语法格式如下:
db.col_1.find({name:'zhangsan',age:18}).pretty()
6. OR 条件
db.col_1.find({$or:[{name:'zhangsan'},{age:20}]}).pretty()
7.AND 和 OR 联合使用
db.col_1.find({"likes":{$gt:50},$or:[{age:20},{phone:15633577595}]}).pretty()
7.$exists()
$exists,用于查询集合中存在某个键的文档或不存在某个键的文档,例如查询col_1集合中存在name键的所有文档
db.col_1.find({name:{$exists:1}})
8. $in和$nin
查询年龄在18,19,20在这个区间的文档
db.col_1.find({age:{$in:[18,19,20]}})
查询年龄不在18,19,20在这个区间的文档
db.col_1.find({age:{$nin:[18,19,20]}})
MongoDB - 索引
索引就是用来加速查询的。数据库索引与书籍的索引类似:有了索引就不需要翻遍整本书,数据库则可以直接在索引中查找,使得查找速度能提高几个数量级。在索引中找到条目以后,就可以直接跳转到目标文档的位置。
1. 查看索引
getIndexes 查看集合索引情况
db.col_1.getIndexes()
db.collection.stats() 查看索引状态
db.col_1.stats()
2. 创建索引
创建普通索引,使用命令 db.collection.ensureIndex({key:1})
db.col_1.ensureIndex({key:1})
3. 删除索引
删除索引(不会删除 _id 索引)
db.col_1.dropIndexes()
db.col_name.dropIndex({key: 1})
4. _id索引
对于每个插入的数据,都会自动生成一条唯一的 _id 字段,_id 索引是绝大多数集合默认建立的索引
> db.col_1.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
> db.col_1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_1"
}
]
字段解释:
v 表示 version,在 Mongo3.2 之前的版本中,会存在 {v:0}(版本锁为0)的情况。在3.2之后的版本中,{v:0} 不再允许使用,这部分可以不去关注,因为 v 由系统自动管理
key 表示作为索引的键。1 或 -1表示排序模式,1为升序,1为降序
name 表示索引的名字,默认生成名称的规则是作为索引的字段_排序模式
ns 表示 namespace 命名空间,由数据库名称.集合名称组成
5.多键索引
单键索引的值为一个单一的值,多键索引的值有多个数据(如数组)
如果mongoDB中插入数组类型的多键数据,索引是自动建立的,无需刻意指定
> db.col_1.insert({z:[1,2,3,4,5]})
WriteResult({ "nInserted" : 1 })
> db.col_1.find()
{ "_id" : ObjectId("59658e56aaf42d1c98dd95a2"), "x" : 10 }
{ "_id" : ObjectId("5965923eaaf42d1c98dd95a3"), "y" : 20 }
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }
> db.col_1.find({z:3})
{ "_id" : ObjectId("59659828aaf42d1c98dd95a4"), "z" : [ 1, 2, 3, 4, 5 ] }
6.符合索引
同时对多个字段创建索引
> db.col_2.insert({x:10,y:20,z:30})
WriteResult({ "nInserted" : 1 })
> db.col_2.find()
{ "_id" : ObjectId("59659a57aaf42d1c98dd95a5"), "x" : 10, "y" : 20, "z" : 30 }
> db.col_2.createIndex({x:1,y:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.col_2.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "runoob.col_2"
},
{
"v" : 2,
"key" : {
"x" : 1,
"y" : 1
},
"name" : "x_1_y_1",
"ns" : "runoob.col_2"
}
]
7.全文索引
场景:全网站关键词搜索
key-value 中,key 此时为 $**(也可以是具体某 key),value 此时为一个固定的字符串(如 text)
全文索引相似度,与 sort 函数一起使用效果更好
db.col_1.find({ $text: { $search: "aa bb" } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } })
注意:
- 每个集合只能创建一个全文索引
- MongoDB 从 2.4 版本开始支持全文检索,从 3.2 版本开始支持中文
(好像)只能对整个单词查询,不能对单词的截取部分查询 - 关键词之间的空格表示或
- 关键词之前的 - 表示非
- 关键词加引号表示与 (需用 \ 转义)
MongoDB - 备份与恢复
MongoDB提供了备份和恢复的功能,分别是MongoDB下载目录下的mongodump.exe和mongorestore.exe文件
备份数据库
备份数据使用下面的命令:
mongodump -h dbhost -d dbname -o dbdirectory
-h:MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:需要备份的数据库实例,例如:test
-o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
mongodump -h 127.0.0.1:27017 -d hrabbit -o /Users/mrotaku/Desktop/dump
恢复数据库
恢复数据使用下面的命令:
mongorestore -h dbhost -d dbname -directoryperdb dbdirectory
-h:MongoDB所在服务器地址
-d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
-directoryperdb:备份数据所在位置,例如:c:\data\dump\test
mongorestore -h 127.0.0.1:27017 -d hrabbit -directoryperdb /Users/mrotaku/Desktop/dump
导出数据
导出数据可以使用命令:
mongoexport -h dbhost -d dbname -c collectionName -o output
参数说明:
-h 数据库地址
-d 指明使用的库
-c 指明要导出的集合
-o 指明要导出的文件名
mongoexport -h127.0.0.1:27017 -dhrabbit -c col_1 -o output
导入数据
导出数据可以使用命令:
mongoimport -h dbhost -d dbname -c collectionname 文件的地址...
参数说明:
-h 数据库地址
-d 指明使用的库
-c 指明要导入的集合
本地的文件地址...
mongoimport -h 127.0.0.1:27017 -d hrabbit -c col_2 /Users/mrotaku/Desktop/dump/hrabbit/c1.bson
安全和认证
每个MongoDB实例中的数据库都可以有许多用户。如果开启了安全性检查,则只有数据库认证用户才能执行读或者写操作。
在认证的上下文中,MongoDB会将普通的数据作为admin数据库处理。admin数据库中的用户被视为超级用户(即管理员)。
在认证之后,管理员可以读写所有数据库,执行特定的管理命令,如listDatabases和shutdown。
在开启安全检查之前,一定要至少有一个管理员账号。
use admin;
db.addUser(“root”,”root”);
在col_1 中创建普通账号:
use col_1;
db.addUser(“zhangsan”,”123”);
db.addUser(“lisi”,”123”,true);
注意:用户lisi,密码为123,对col_1数据库拥有读写权限
用户zhangsan,密码为123,对col_1数据库拥有只读权限
重新启动数据库服务,并开启安全检查:
mongod --dbpath /Users/mrotaku/Desktop/nosql --auth