ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 前景 随着大数据的不断发展,非关系型数据库已经变得越来越重要,相关的产品也都得到了飞速发展。而其中 MongoDB 更是佼佼者,作为高性能开源文档数据库,MongoDB 以敏捷、可扩展和对企业应用友好而著称,因其操作简单、完全免费、源码公开等特点,受到了 IT 从业人员的青睐,并被广泛部署于实际的生产环境中。 使用 MongoDB 的公司包括:BAT、360、Foursquare、Craiglist、迪士尼、SAP、Intuit、EA 等。 ## 定义 MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。MongoDB 最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。 ## 优点 MongoDB 的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有: * 面向集合存储,易存储对象类型的数据。 * 模式自由。 * 支持动态查询。 * 支持完全索引,包含内部对象。 * 支持查询。 * 支持复制和故障恢复。 * 使用高效的二进制数据存储,包括大型对象(如视频等)。 * 自动处理碎片,以支持云计算层次的扩展性 * 支持 JavaScript,RUBY,PYTHON,JAVA,C++,PHP 等多种语言。 * 文件存储格式为 BSON(一种 JSON 的扩展) ## BSON BSON 是一种类似 JSON 的二进制形式的存储格式,简称 Binary JSON,它和 JSON 一样,支持内嵌的文档对象和数组对象,但是 BSON 有 JSON 没有的一些数据类型,如 Date 和 BinData 类型。 后面存在 MongoDB 数据库里面的全部都是 BSON 格式的数据。 # MongoDB 使用 对 MongoDB 数据库操作需要其提供的内置命令来操作的。 ## 基本命令 * show dbs :查看有数据的库 * use 库名 :若没有则创建库并切换,若有只切换库 * db :显示当前操作的库 * db.runCommand({"dropDatabase": 1}):删除当前数据库,注意此处的 1 没加双引号 ## 集合操作 * show collections :显示库中的集合 * db.createCollection("集合名字") : 创建集合 * db.集合名.drop() 或 db.runCommand({"drop":"集合名"}) :删除集合 ## 文档操作 ### 增加文档 给某集合里面增加文档,注意: * 若集合不存在,会自动创建集合。 * 保存成功之后,系统会自动给文档增加一个 \_id 主键字段,主键是每个文档的唯一标识,其值不能重复,就像身份证是每个人编号是唯一的。 语法格式如下: * db.集合名.insert(BSON 格式数据),若新增的文档主键已经存在,insert 会不做操作并提示错误。 * db.集合名.save(BSON 格式数据),若新增的文档主键已经存在,save 则更改原来的内容为新内容。 ~~~ db.students.insert({"name":"xx","age":18}) ​ db.students.insert({"_id":ObjectId("5c457f78034a8e64b22cd683"),"name":"xx","age":19}) // 报错 duplicate field error collection db.students.save({"_id":ObjectId("5c457f78034a8e64b22cd683"),"name":"xx","age":19}) // 修改 ~~~ ### 查询文档 查询集合中的文档,语法格式如下: * db.集合名.find() :查询集合中所有文档 * db.集合名.find().pretty() :格式化查询到的文档 * db.集合名.findOne()     :查询集合中的第一个文档,即插入最早那个 ~~~ db.students.find() db.students.find().pretty()           db.students.findOne() ~~~ ### 修改文档 修改集合中的文档,语法格式如下: * db.集合名.update(BSON 格式数据):注意:第一个参数查询的条件,第二个参数是修改的内容,但主键是不能修改。 ~~~ db.students.update({"name":"xx"}, {"age":88})                       // 注意原来的数据只剩下 {"age":88} db.students.update({"name":"xx"}, {$set:{"age":88}})               // 这里就只改原来文档的 age 的值。   db.students.update({"name":"xx"}, {$set:{"age":88}}, {multi:true}) // 默认只改先找的一条,若想改多条得设置 multi 参数为 true ~~~ ### 删除文档 删除集合中的文旦,语法格式如下: * db.集合名.remove() :删除集合中的文档,可以指定条件 ~~~ db.集合名.remove({})               // 删除集合中所有的文档 db.集合名.remove({"name":"yy"})     // 删除指定条件 name="yy" 的文档 ~~~ ## 高级查询 * 查询 field = value 的文档语法:db.集合名.find({ "field" : value }) ~~~ // 查询女歌星,即查询 sex = "女"的歌星 db.singers.find({"sex":"女"}) ~~~ * 查询 field > value 的文档语法:db.集合名.find({ "field" : { $gt: value } }) ~~~ // 查询年龄大于 53 的歌星 db.singers.find({"age": { $gt: 53 }}) ~~~ * 查询 field < value 的文档语法:db.集合名.find({ "field" : { $lt: value } }) ~~~ // 查询年龄小于 35 岁的歌星 db.singers.find({"age": { $lt: 35 }}) ~~~ * 查询 field >= value 的文档语法:db.集合名.find({ "field" : { $gte: value } }) ~~~ // 查询成绩大于等于 95 的歌星 db.singers.find({"score": { $gte: 95 }}) ~~~ * 查询 field <= value 的文档语法:db.集合名.find({ "field" : { $lte: value } }) ~~~ // 查询年龄在小于等于 32 岁的歌星。 db.singers.find({"age": { $lte: 32 }}) ~~~ * 查询 min < field < max 的文档语法:db.集合名.find({ "field" : { lt: max } }) ~~~ // 查询年龄在 (30, 40) 岁之间的歌星 db.singers.find({"age": { $gt: 30 , $lt: 40 }}) ~~~ * 查询 field != value 的文档语法:db.集合名.find({ "field" : { $ne: value } }) ~~~ // 查询外国歌手 db.singers.find({"country": { $ne: "中国" }}) ~~~ * 查询 field % divisor == remainder 的文档语法:db.集合名.find({ "field" : { $mod : \[ divisor, remainder \] } }) ~~~ // 查询成绩为 5,15,25...95 的歌星。 db.singers.find({"score" : { $mod : [10, 5] }}) ~~~ * 查询 field = value1 OR field = value2 ... OR field = valueN OR 的文档语法:db.集合名.{ field: { $in: \[value1, value2, ... valueN \] } } ~~~ // 查询序号(num)为 3 或者 6 或者 9 的歌星 db.singers.find({ "num" : { $in: ["3", "6", "9"] } }) ~~~ * 查询 field value2 ... AND field <> valueN 的文档语法:db.集合名.{ field: { $nin: \[value1, value2, ... valueN \] } } ~~~ // 查询国籍不为美国和韩国的歌手 db.singers.find({"country" : { $nin: ["美国", "韩国"] }}) ~~~ * 查询文档字段数量的语法:db.集合名.find({ "field" : { $size: num } }),注意 field 的值是数组。 ~~~ // 查询有 3 个代表作品的歌手 db.singers.find({"works" : { $size: 3 }}) ~~~ * 查询存在或不存在某个字段的的文档语法:db.集合名.find({ "field" : { $exists : true|false } }) ~~~ // 查询包含 name 字段的歌手 db.singers.find({"name" : { $exists : true }}) ~~~ * 查询多个条件是或的关系的文档语法:db.集合名.find({ $or : \[expression1, expression2, ..., expressionN\] }) ~~~ // 查询名词是刘德华的歌手或者是女歌手 db.singers.find({$or : [{"name":"刘德华"}, {"sex":"女"}]}) ~~~ * 查询多个条件是且的关系的文档语法:db.集合名.find({ $and : \[expression1, expression2, ..., expressionN\] }) ~~~ // 查询名字是刘德华且是女的歌手 db.singers.find({$and : [{"name":"刘德华"}, {"sex":"女"}]}) ~~~ * 若字段的值是对象的查询 ~~~ db.students.insert({"name":"zs", "score":{"yw":80, "sx":91}}) db.students.insert({"name":"ls", "score":{"yw":77, "sx":95}}) // 查询语文成绩为 80 的同学 db.students.find({"score.yw": 80}) ~~~ * 排序查询文档,语法格式:db.集合名.find().sort({ "field" : -1 | 1}),注意 1 代表升序,-1 代表降序 ~~~ // 对所有歌星安年龄排序 db.singers.find().sort({"age": 1}) ~~~ * 限制查询的个数,语法格式:db.集合名.find().limit(n) ~~~ // 实现输出 5 条 db.singers.find().limit(5) ~~~ * 跳过多少条再查询,语法格式:db.集合名.find().skip(n) ~~~ // 跳过 5 条查询 db.list.find().skip(5) ~~~ * 分页查询:语法格式:db.集合名.find().skip(n).limit(n) ``` // 假如 101 条数据,每页显示 10 条,一共分 11 页,那么要查询第 2 页的文档 // var pageSize = 10; // var start = (2 - 1) * pageSize; db.list.find().skip(start).limit(pagesize) ```