MongoDB数据库介绍
介绍
MongoDB是一个文档数据库,它保存的文档是由成对字段和值组成的数据结构,而字段对应的值可以包括其他文档,数组等,文件存储格式为BSON (JSON的一种) 如
{name:"MongoDb",
class:"NoSQL",
groups:["Redis", "MongoDB","HBase"],
structure:{"structure_1":{"structure_2":“value”}},
MongoDB也是一个非关系型数据库,主要用作海量存储。功能丰富,由于是C++语言进行编写,所以性能比较高。
特点:
- 高性能:C++语言进行编写,拥有较高的性能
- 易扩展: 数据之间没有关系,所以容易拓展
- 大数据量: 使用高效的二进制数据存储,可以保存大型文件
- 高可用性: 自动故障转移,数据冗余 (防止丢失数据)
- 支持索引: 加快查询速度,而且可以进行数据去重
- 丰富的查询语言: Python,JAVA, C++等
官方文档入口:https://docs.mongodb.com/manual/introduction/
常见配置:
- –dbpath :数据存储位置
- –logpath :日志存储位置,如果不指定日志文件,那么日志会在终端中进行显示
- –logapend: 日志追加模式
- –port: 指定端口,默认27017
- –bind_ip: 指定ip
- –f : 以指定配置文件方式启动
MongoDB数据库指令
数据库操作:
- 服务端启动:sudo service mongod start
- 服务端停止:sudo service mongod stop
- 客户端启动: mongo
- 帮助:mongo --help
- 客户端退出: exit
- 查看当前所在数据库: bd
- 查看所有数据库: show databases | show dbs
- 切换数据库: use db_name
- 删除当前数据库:db.dropDatabase()
注意点
- 当切换数据库时,若使用一个没有的数据库名,会默认创建一个新的数据库,这个数据库只存在内存中,此时使用显示所有数据库,只会显示存在磁盘中的数据库,不会显示该数据库,只有该数据库中存入数据和创建集合时,才能被显示
- 启动客户端后,如果没有进行切换数据库,默认会在test数据库中操作
- MongoDB数据库有些指令和MySQL数据库指令操作相似,可以对比学习
集合操作:
- 查看所有集合: show collections
- 创建一个集合: db.createCollection(“collection_name”)
- 创建一个有存储上限的集合:db.createCollection(“collection_name”, {capped:true, size:size_number})
- 判断集合是否有上限:db.collection_name.isCapped()
注意点
- 集合默认是没有存储上限的
- capped字段表示是否设置存储上限,这里使用布尔值时要纯小写,否则会报错
- 如果设置了capped为flase,且同时设置了size,不会报错,相当于设置了没有存储上限
- 如果设置size的值小于256,则会按照256个字节为上限,如果大于256个字节才会按照设定值为存储上限
- 如果集合达到存储上限,不会报错,它会存入新数据,删除最老的数据,可以利用此机制来存储日志记录之类的文件
数据操作:
增:
- 插入(insert)单条数据: db.collection_name.insert({“key”:“value”})
- 插入(insert)多条数据: db.collection_name.insert([{“key”:“value”},{“key_1”:“value_1”}])
- 插入(save)单条数据: db.collection_name.save({“key”:“value”})
- 插入(save)多条数据:db.collection_name.save([{“key”:“value”},{“key_1”:“value_1”}])
- upsert单条数据: db.collection_name.save({"_id":“ObjectId”,“key”:“value”})
注意点
- 插入多条数据时,如果漏写中括号(如:.insert({“name”:“No1”},{“name”:“No2”})指令 ),只会插入第一条数据,只能查询到No1
- upsert操作:有则更新,无则插入
- save执行upsert只能单条操作,若使用中括号进行多条数据操作,只能进行插入,不能进行更新,如果id已经存在,会报错
- 在输入kv形式数据的时候, key的双引号可以省略, 但是value的双引号不可省略,除非value为数字类型
- 如果插入时没有指定id, 则系统会自动分配id: 时间戳 + 机器id + 服务进程id + 增量值, 增量值主要是为了避免在同一时间戳插入的数据id一样。这个id默认有索引。
查:
- 查询所有数据: db.collection_name.find()
- 查询指定数据: db.collection_name.find({key:“value”})
- 包含查询数据: db.collection_name.find({key: /partial_value/})
- 比较查询数据: db.collection_name.find({key:{$gte: number}})
- 逻辑查询数据: db.collection_name.find({$and:[{key:“value”},{key_2:“value_2”}]})
- 范围查询数据: db.collection_name.find({key:{$in:[key_1,key_2,…]}})
- 正则查询数据: db.collection_name.find({key:{$regex:"^A"}})
- 自定义查询数据: db.collection_name.find($where:function(){return this.age > 30})
注意点
- 查询指定数据时,如果查询不到数据,是不会报错的。
- 包含查询时,会输出所有key中包含partial_value的数据,但是键对于的value要是字符串才能被找到
- 常用的比较运算符
小于$lt 小于等于$lte 大于$gt 大于等于$gte 不等于$ne
- 逻辑查询常用
$and $or
- 范围查询中,
$in
表示存在列表中就显示,而$nin
表示存在列表中就不显示 - 正则查询时
$regex:“正则表达式”
- 自定义查询时,需要自己定义函数进行查询,使用较少
- 上面是简单的使用,但是查询具有很大的灵活性,有时候这几种需要配合使用
- MongoDB的难点不在于语法,而在于多层括号
查询结果处理:
- limit处理:db.collection_name.find(条件).limit(n)
- skip处理:db.collection_name.find(条件).skip(n)
- sort处理:db.collection_name.find(条件).sort({“key”:1, “key_2”:-1,…})
- distinct处理:db.collection_name.distinct(“key”)
- distinct处理二:db.collection_name.distinct(“key”,{条件})
- count处理: db.collection_name.find(条件).count()
- count简略写法:db.collection_name.count(条件)
- 字段过滤处理:db.collection_name({条件},{“key”:1,“key_1”:1})
注意点
- limit()若不填入数值,则默认显示全部
- skip(0若不填入数据,则默认不跳过数据
- limit 和 skip 配合使用时,不论两者顺序前后,结果一样,可以理解为skip优先级高, 即.skip(1).limit(2) = .limit(2).skip(1)
- sort()对于的数字为1则为正序,而为-1则为降序,字段一相同时才安装字段二规定的方式排序
- distinct处理处理时,区别于其他处理方式没有使用find,处理一表示对表中所有数据进行去重,只显示去重后设置的key,而如果想限定范围,使用处理方法二
- 字段过滤处理,除了
_id
字段名,其他字段只能全为1或0(1为显示,0为不显示),不能0和1同时出现
改:
- 覆盖更新:db.collection_name.update({条件}, {“key_1”:“value_1”,…})
- 键值对更新:db.collection_name.update({条件}, {$set: {“key_1”:“value_1”,…}})
- 批量键值对更新:db.collection_name.update({条件}, {$set: {“key_1”:“value_1”,…}, {multi:true}})
- upsert更新:db.collection_name.update({条件}, {$set: {“key_1”:“value_1”,…}, {upsert:true}})
注意点
- update默认只更新第一条符合条件的数据(若条件为空,所有数据都符合条件),当设置了multi参数为true时,支持多条更新
- multi参数必须和$符号一起使用!
- 在使用$set更新方式时,如果数据中要更新的key存在,那就进行覆盖,如果不存在进行添加新key-value
- upsert更新,当按照条件找到数据时,按设定的更新方式进行更新,如果没有找到数据,则新建数据,再按设定的更新方式进行更新
删:
- 删除所有数据: db.collection_name.remove({})
- 删除特定数据: db.collection_name.remove({条件})
- 删除第一条特定数据:db.collection_name.remove({条件}, {justOne:true})
注意点
- remove默认删除所有符合条件的数据