MongoDB 数据库-自学
MongoDB 简介
MongoDB 数据库是一种 NoSQL 数据库,NoSQL 数据库不是这几年才有的,从数据库的初期发展就已经存在有了 NoSQL 数据库。数据库之中支持的 SQL 语句是由 IBM 开发出来的,并且最早就应用在了 Oracle 数据库,但是 SQL 语句的使用并不麻烦,就是几个简单的单词:SELECT、FROM、WHERE、GROUP BY、HAYING、ORDER BY。但是在这个时候有人开始反感于编写 SQL 操作。于是有一些人开始提出一个理论 ———— 不要去使用SQL,于是最早的 NoSQL 概念产生了。可是后来的发展产生了一点变化,在90年代到2010年之间,世界上最流行的数据库依然是关系型数据库,并且围绕着关系型数据库开发出了大量的程序应用,后来又随着移动技术(云计算、大数据)的发展,很多公司并不愿意使用大型的厂商数据库 ———— Oracle、DB2,因为这些人已经习惯于使用 MySQL 数据库了。这些人发现在大数据以及云计算的环境下,数据存储受到了很大的挑战,那么后来就开始重新进行了 NoSQL 数据库的开发,但是经过长期的开发发现,NoSQL 数据库依然不可能离开传统的关系型数据库(NoSQL、Not Only SQL)。
实际上在显示的开发中一直存在一种神奇的问题:
- 数据表 -> JDBC 读取 -> POJO(VO、PO)-> 控制层转化为 JSON 数据 -> 客户端
可是这样的转换实在是太麻烦了,那么最好的做法是,直接有一个数据库就存放有要显示的 JSON 数据该有多好,那么就省略了所有需要进行转换的过程。所以在实际的开发之外还要提供有一个 NoSQL 数据库,其中 NoSQL 数据库负载数据的读取,因为直接保存的就是 JSON(前提:MongoDB 中的数据是排列好的组合数据)。
例如:现在要去显示出每个雇员的编号、姓名、职位、部门名称、工作等级。传统的关系型数据库,一定要存放大量的冗余数据,不合理。而有了 NoSQL 数据库之中,可以直接在业务层面讲数据交给 NoSQL 保存,按照指定的结构进行存储。
在 MongoDB 数据库之中与 Oracle 数据库有如下的概念对应:
No | 关系型数据库 | NoSQL 数据库 |
---|---|---|
1 | 数据库 | 数据库(类似于 MySQL) |
2 | 表 | 集合 |
3 | 行 | 文档 |
4 | 列 | 成员 |
5 | 主线 | Object ID(自动维护的) |
在整个行业之中,MongoDB 数据库是发展最好的一个 NoSQL 数据库,因为它于 Node.js 捆绑了。如果你要从事 Node.js 开发,那么一定要使用 MongoDB,而 Node.js 在国内最成功的应用 ———— 淘宝。
MongoDB 之所以能够更好的发展也取决于:面向集合的存储过程、模式自由(无模式)、方便的进行数据的存储扩充、支持索引、支持短暂数据保留、具备完整的数据库状态监控、基于 BSON 应用。
安装并配置 MongoDB
如果想要得到 MongoDB 数据库只需要登录 中文网 可以直接下载可用版本,最新的版本是 3.0.x,但是这版本变为了 windows 安装版(只是把原来的解压缩版变为了安装拷贝)。
将下载下来的 MongoDB 数据库直接进行安装。安装的时候需要选择好对应的操作系统,本次使用的是 64 位的安装版本。存放在 E:/ 盘
MongoDB 安装完成之后,严格来讲并不能够在 Windows 下使用,需要为它配置 path 环境属性 E:/MongoDB/bin
如果想要正常启动 MongoDB 数据库,那么必须建议一个文件夹,这个文件夹将保存所有的数据库的信息,现在将在 MongoDB 文件夹之中建立一个 db 的目录,并且在此目录下保存所有的数据文件。
MongoDB 数据库的启动需要使用 mongod.exe 命令完成,启动的时候可以设置端口号,也可以不设置端口号。
- 不设置端口号启动 MongoDB 服务:
mongod --dbpath E:/MongoDB/db
- 设置端口号启动:
mongod --dbpath E:/MongoDB/db --port=27000
- 如果日后需要通过程序访问数据库的话,那么一定要设置端口号。
当 MongoDB 服务启动之后,可以使用 mongo
命令链接数据库
范例:查询所有的数据库 show databases
此时只存在有一个 local 的本地数据库,不过这个数据库不使用
虽然以上的代码实现了数据库的启动与链接操作,但是从严格意义上来讲,以上的代码没有任何用处,因为从实际的开发来讲,在 MongoDB 启动的时候需要设置一些相应参数:端口号、是否启用用户验证、数据文件的位置等等。
范例:在 E:/MongoDB 目录下建立一个文件 “mongodb.conf”
- 同时建立了一个保存日志信息的文件:log/mongodb.log
# 设置数据目录的路径
dbpath = C:\Users\zhujunlin001\Desktop\MongoDB-self-study\mongodb-win32-x86_64-windows-4.4.2\db
# 设置日志信息的文件路径
logpath = C:\Users\zhujunlin001\Desktop\MongoDB-self-study\mongodb-win32-x86_64-windows-4.4.2\log\mongodb.log
# 打开日志输出操作
logappend = true
# 表示目前为止不使用任何验证的登录,在以后进行用户管理的时候使用它
noauth = true
# 设置端口号
port = 27001
- 随后重新启动 MongoDB 数据库服务:
- 切换到 admin 数据库:
use admin
- 关闭数据库服务:
db.shutdownServer()
- 重新启动服务:
mongod -f e:\MongoDB\mongodb.conf
mongod -f C:\Users\zhujunlin001\Desktop\MongoDB-self-study\mongodb-win32-x86_64-windows-4.4.2\mongodb.conf
- 切换到 admin 数据库:
范例:链接数据库
此时服务器已经存在有指定的端口号了。mongo --port=21001
使用端口号启动在日后的程序开发部分是非常有用处的。
MongoDB 的基础操作
在 MongoDB 数据库里面是存在数据库的概念,但是没有模式(所有的信息都是按照文档保存的)保存数据的结构就是 JSON 结构,只不过在进行一些数据处理的时候才会使用到 MongoDB 自己的一些操作符。
- 使用 mldn 数据库:
use mldn
- 实际上这个时候并不会创建数据库,只有在数据库里面保存集合数据之后才能够真正创建数据库
- 创建一个集合 ———— 创建一个 emp 集合
db.createCollection("emp")
- 这个时候 mldn 数据库才会真正的存在。
- 但是很多的时候如果按照以上的代码形式进行会觉得你不正常,因为正常人使用 MongoDB 数据库集合操作的时候,都是直接向里面保存一个数据。
- 执行:
db.dept.insert({"deptno":10, "dname":"财务部", "loc":"北京"})
- 查看所有集合
show collections
发现 dept 集合自动创建了。 - 查看 emp 表的数据
- 语法:
db.集合名称.find({若干条件})
- 执行:
db.dept.find()
从传统的数据表来看(集合就想到与表的结构),表的结构一旦定义就必须按照其定义的要求进行内容的编写,但是 MongoDB 不一样,它可以自己随意扩充数据。
- 增加不规则数据
var deptData = {
"deptno": 20,
"dname": "研发部",
"loc": "深圳",
"count": 20,
"avg": 8000
}
db.dept.insert(deptData)
此时 dept 集合的内容可以有用户随便去定义,完全不用考虑其它的结构,那么实际上就必须明确一点了,在 MongoDB 数据库之中是绝对不可能存在查看集合结构的操作。
7. 关于 ID 的问题
在 MongoDB 集合中的每一行记录都会自动的生成一个 "_id": ObjectId("1234987sadf90980989sadf")
数据,这个组成是:时间戳 + 机器码 + PID + 计数器
这个 ID 的信息是 MongoDB 数据库自己为用户生成的
-
查看单独的一个文档信息
db.dept.findOne()
-
删除数据
db.dept.remove({"_id": ObjectId("1234987sadf90980989sadf")})
-
更新数据
var deptData = {
"deptno": 21,
"dname": "家里蹲",
"loc": "北京",
"count": 20,
"avg": 8100
}
db.dept.updata({"_id": ObjectId("1234987sadf90980989sadf")}, deptData)
- 删除集合
- 语法:
db.集合名称.drop()
- 这里执行:
db.dept.drop()
- 删除数据库(删除当前所在的数据库)
db.dropDatabase()
删除数据库的是,删除当前所在的数据库,必须先切换到数据库后,才能删除。
数据操作(重点)
只要是数据库,那么就绝对离不开最为核心的功能:CRUD(增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)),所以在 MongoDB 里面对于数据的操作也是有支持的,但是需要提醒的是,除了增加之外,其它的都很麻烦。
数据增加
- 使用:
db.集合.insert()
可以实现数据的增加操作- 范例:增加一个简单数据
db.infos.insert({"url":"www.mldn.cn"})
- 范例:增加一个数组
db.infos.insert([{"url":"www.mldn.cn"}, {"url":"www.mldnjava.cn"}])
如果要想保存多个数据,那么就使用数组。 - 范例:保存 10000 个数据?
如果数据保存很多的情况下,列表时不会全部列出,它只会列出部分的内容for (var x = 0; x < 10000; x ++) { db.infos.insert({"url": "mldn -" + x}); };
- 范例:增加一个简单数据
数据的查询操作
任何的数据库之中,数据的查询操作都是最为麻烦的,而在 MongoDB 数据库里面,对于查询的支持非常的到位,包含有关系运算、逻辑运算、数组运算、正则运算等等。
首先对于数据的查询操作核心的语法:db.集合.find({查询条件}[,{设置显示的字段}])
。
范例:最简单的用法就是直接使用 find() 函数完成查询 db.infos.find()
范例:希望查询出 url 为 “www.mldn.cn” 的数据 db.infos.find({"url": "www.mldn.cn"})
发现在进行数据查询的时候也是按照 JSON 形式设置的相等关系。它的整个开发之中都不可能离开 JSON 数据。
对于设置的显示字段严格来讲就称为数据的投影操作,如果不需要显示的字段设置“0”,而需要显示的字段设置为“1”。
范例:不想显示 “_id” db.infos.find({"url": "www.mldn.cn"}, {"_id": 0, "url": 1})
大部分情况下,这种投影操作的意义不大。同时对于数据的查询也可以使用 “pretty()” 函数进行漂亮显示
范例:漂亮显示 db.infos.find({"url": "www.mldn.cn"}, {"_id": 0, "url": 1}).pretty()
数据列多的时候一定可以看出华丽的显示效果。其实就是将数据排好格式了。
范例:查询单个数据 db.infos.findOne({"url": "www.mldn.cn"}, {"_id": 0, "url": 1})
利用以上的查询可以实现格式化的输出效果,前提:列的内容必须多。
条件过滤
实际上习惯于传统关系型数据库开发的我们对于数据的筛选,肯能首先想到的一定是 where 字句,所以在 MongoDB 里面也提供有“$where”。
-
$exists
+ 语法:{ field: { $exists: <boolean> } }
+ $exists如果为true,则选择包含该字段的文档。如果 为false,则查询仅返回不包含该字段的文档。null ?不返还 -
$where
+
+ 范例:使用 where 进行数据查询db.students.find({"$where": "this.age>20"}).pretty()
+ 简化db.students.find("this.age>20").pretty()
对于“$where”是可以简化的,但是这类的操作是属于进行每一行的信息判断,实际上对于数据量较大的情况并不方便使用。实际上以上的代码严格来讲是属于编写一个操作的函数。
MongoDB 的语法完全可以使用 JavaScript 来写,所以以上代码等同于(也可以用一下写法)
```javascript
db.students.find(function() {
return this.age > 20;
}).pretty();
// 或者
db.students.find({"$where": function() {
return this.age > 20;
}}).pretty();
```
一上只是实现了一个条件的查询,如果要实现对个条件的判断查询,那么就需要使用 and 连接。
- $and
范例:在 students 集合里找到年龄是 20 的人:
```javascript
db.students.find({"$and": [
{"$where": "this.age > 19"},
{"$where": "this.age < 21"}
]}).pretty();
```
虽然这种形式的操作可以实现数据查询,但是最大的缺点是将在 MongoDB 里面保存的 BSON 数据变为了 JavaScript 的语法结构,这样的方式不方便使用数据库的索引机制。
正则运算
如果要实现模糊查询,那么必须使用正则表达式,而且正则表达式使用的语言 Perl 兼容的正则表达式的形式。如果要想实现正则使用,则按照如下的格式定义:
- 基础语法:
{key: 正则标记}
- 完整语法:
{key:{"$regex": 正则标记, "$options": 选项}}
- 对应 options 主要是设置正则的信息查询的标记:
- “i”:忽略字母大小写
- “m”:多行查找
- “x”:空白字符除了被转义的或在字符类中意外的完全被忽略
- “s”:匹配所有的字符(圆点、“.”),包括换行内容
- 需要注意的是,如果是直接使用(JavaScript)那么只能够使用 i 和 m,而“x”和“s”必须使用“$regex”
- 对应 options 主要是设置正则的信息查询的标记:
范例:查询以 “谷” 开头的姓名
db.students.find({"name": /谷/}).pretty();
范例:查询名字中有字母 A 的
db.students.find({"name": /a/i}).pretty();
// 完整的格式写法
db.students.find({"name": {"$regex": /a/i}}).pretty();
如果要执行模糊查询的操作,严格来讲只需要编写一个关键字就够了。
正则操作之中除了可以查询出单个字段的内容之外,也可进行数组数据的查询。
范例:查询数组数据: course 课程,是个数组,现需要查询这个数组中的课程带“语”关键字的数据
db.students.find({"course": /语/}).pretty();
// 或者
db.students.find({"course": /语?/}).pretty();
MongoDB 中的正则符号和之前 java 正则是有一些差别的,不建议使用以前的一些标记,正则就将其应用在模糊数据的查询上
数据排序
在 MongoDB 里面数据的排序操作使用 “sort()” 函数,在进行排序的时候可以有两个顺序:升序(1)、降序(-1)。
范例:按成绩"score"经行倒序排。
db.students.find().sort("score": -1).pretty();
但是在进行排序的过程里面有一种方式称为自然排序,按照数据保存的先后顺序排序,使用“$natural”。
范例:自然排序
db.students.find().sort("$natural": -1).pretty();
在 MongoDB 数据库里面排序的操作相比较传统关系型数据库的设置要简单。
分页控制
在 MongoDB 里面的数据分页显示也是符合于大数据要求的操作函数:
- skip(n): 表示跨过多少数据行
- limit(n): 取出的数据行的个数限制。
范例:分页显示(第一页,skip(0)、limit(5))
db.students.find().skip(0).limit(5).sort({"age": 1}).pretty();
范例:分页显示(第二页,skip(5)、limit(5))
db.students.find().skip(5).limit(5).sort({"age": 1}).pretty();
这两个分页的控制操作,就是在以后只要是存在有大数据的信息情况下都会使用它。
更新函数(数据更新操作)
对于 MongoDB 而言,数据的更新基本上是一键很麻烦的事情,如果在实际的工作之中,真的具有此类的操作支持,那么最好的做法:
在 MongoDB 里面对于数据的更新操作提供了两类函数: save()、updata()。
函数的基本使用
如果要修改数据最直接的使用函数就是 updata(),但是这个函数的语法要求很麻烦:
- 语法:
db.集合.updata(更新条件,新的对象数据(更新操作符),upsert,multi)
- upsert:如果要更新的数据不存在,则增加一条新的内容(true为增加,false为不增加)
- multi:表示是否只更新满足条件的第一行记录,如果设置为false只更新第一个,如果是true全更新
范例:更新存在的数据 ———— 将年龄是19岁的人的成绩"score"都更新为100分(此时会返回对跳数据)
- 选择只更新第一天数据
db.students.updata({"age": 19}, {"$set": {"score": 100}}, false, false);
- 所有满足条件的数据都更新
db.students.updata({"age": 19}, {"$set": {"score": 100}}, false, true);
范例:更新不存在的数据 ————
db.students.updata({"age": 30}, {"$set": {"name": "不存在"}}, true, false);
由于没有年龄是30岁的学生信息,所以此时相当于进行了数据的创建。
那么处理 updata() 函数之外还提供有 save() 函数,这个函数的功能与更新不存在的内容相似。
范例:使用 save() 操作
db.students.save({"_id": ObjectId("55932d0f2eeds37d002")}, "age": 50);
由于此时对应的id数据存在了,所以就变为了更新操作,但是如果要保存的数据不存在(不能保存有"_id"),那么就变为了增加操作
一般来说更新操作建议使用 updata()
修改器
对应 MongoDB 数据库而言,数据的修改会牵扯到内容的变更、结构的变更(包含有数组),所以在进行 MongoDB 设计的时候就提供有一系列的修改器的应用,那么像之前使用的 “$set” 就是一个修改器
- $inc: 主要正对于一个数字字段,增加某个数字字段的数据内容。
- 语法:
{"$inc": {"成员": 内容}}
范例:将所有年龄为19岁的学生,成绩一律减少30分,年龄加一岁。
db.students.updata({"age": 19}, {"$inc": {"score": -30, "age": 1}}, false, true);
- $set: 进行内容的重新设置
- 语法:
{"$set": {"成员": 新内容}}
范例:将年龄为20岁的人的成绩修改为 89 分
db.students.updata({"age": 20}, {"$set": {"score": 89}}, false, true);
- $unset: 删除某个成员的内容
- 语法:
{"$unset": {"成员": 1}}
范例:删除"张三"的年龄与成绩的信息
db.students.updata({"name": "张三"}, {"$unset": {"age": 1, "score": 1}});
- $push: 相当于将内容追加到指定成员之中(基本上是数组)
- 语法:
{"$push": {"成员": value}}
范例:向"张三"添加课程信息(此时“张三”信息下没有 course 信息)
db.students.updata({"name": "张三"}, {"$push": {"course": "语文"}});
范例:向"谷大神"的课程信息追加"美术"(此时“谷大神”信息下有 course 信息)
db.students.updata({"name": "谷大神"}, {"$push": {"course": "美术"}});
就是进行数组数据的添加操作使用的,如果没有数组则进行一个新的数组的创建,如果有这进行内容的最加
- $pushAll: 与 "$push" 是类似的,可以一次最加多个内容到数组里
- 语法:
{"$pushAll": {"成员": 数组内容}}
范例:向"王五"的信息里面添加多个课程内容
db.students.updata({"name": "王五"}, {"$pushAll": {"course": ["语文", "美术"]}});
- $addToSet:向数组里面增加一个新的内容,只有这个内容不存在的时候才会增加
- 语法:
{"$addToSet": {"成员": 内容}}
范例:向"王五"的课程信息里面增加新的内容
db.students.updata({"name": "王五"}, {"$addToSet": {"course": "语文"}});
"语文"之前已存在,不会向数组最加内容,如果不存在,则会追加
7. $pop: 删除数组内的数据
- 语法:
{"$pop": {"成员": 内容}}
,内容如果设置为 1 表示删除第一个,如果是 -1 表示删除最后一个
范例:删除"王五"的课程信息里面的第一个课程
db.students.updata({"name": "王五"}, {"$pop": {"course": -1}});
范例:删除"王五"的课程信息里面的最后一个课程
db.students.updata({"name": "王五"}, {"$pop": {"course": 1}});
- $pull:从数组内删除一个指定内容的数据
- 语法:
{"$pull": {"成员": 数据}}
,进行数据比对的,如果是此数据则删除
范例:删除"王五"的"音乐"课程信息
db.students.updata({"name": "王五"}, {"$pull": {"course": "音乐"}});
- $pullAll: 一次性删除多个内容
- 语法:
{"$pull": {"成员": [数据, 数据, 数据]}}
范例:删除"王五"的三门课程信息
db.students.updata({"name": "王五"}, {"$pullAll": {"course": ["音乐", "英语", "数学"]}});
- $rename: 为成员名称重命名
- 语法:
{"$rename": {"旧的成员名称": "新的成员名称"}}
范例:将"张三"成员名称修改为"姓名"
db.students.updata({"name": "张三"}, {"$rename": {"name": "姓名"}});
在整个 MongoDB 数据库里面,提供的修改器的支持很到位。
数据删除
在 MongoDB 里面的数据的删除实际上并不复杂,只需要使用"remove()"函数就可以了
这个函数是有两可选项的:
- 删除条件:满足条件的数据被删除
- 是否只删除一个数据,如果设置为true或者是1表示只删除一个。
范例:清空 infos 集合中的内容
db.infos.remove({});
范例:删除所有姓名里面带有"谷"的信息
db.students.remove({"name": /谷/});
范例:删除姓名里面带有"高"的信息,要求只删除一个
db.students.remove({"name": /高/}, true);
删除操作里面依然需要使用限定查询的相关操作内容。
关系运算(关系查询)
在 MongoDB 里面支持的关系查询操作:大于($gt)、小于($lt)、大于等于($gte)、小于等于($lte)、不等于($ne)、等于(key: value、$eq)。但是要想让这些操作可以正常使用,那么需要准备出一个数据集合
范例:定义一个学生信息集合
db.students.drop();
db.students.insert({"name": "张三", "sex": "男", "age": 18 "score": 89, "address": "海淀区"});
db.students.insert({"name": "李四", "sex": "男", "age": 18 "score": 56, "address": "崇文区"});
db.students.insert({"name": "王五", "sex": "女", "age": 19 "score": 89, "address": "海淀区"});
db.students.insert({"name": "赵六", "sex": "男", "age": 20 "score": 89, "address": "朝阳区"});
db.students.insert({"name": "孙七", "sex": "女", "age": 19 "score": 100, "address": "西城区"});
db.students.insert({"name": "金八", "sex": "男", "age": 18 "score": 89, "address": "海淀区"});
// ...
范例:查询姓名是张三的学生信息
db.students.find({"name": "张三"}).pretty();
范例:查询年龄大于19岁的学生信息
db.students.find({"age": {"$gt": 19}}).pretty();
范例:查询姓名不是王五的信息
db.students.find({"name": {"$ne": "王五"}}).pretty();
此时于之前最大的区别就在于,在一个JSON结构里面需要定义其它的JSON结构,并且这种风格在日后通过程序进行操作的时候依然如此
逻辑运算
逻辑运算主要就是三种类型:于($and)、或($or)、非($not、$nor)
范例:查询年龄在 19~20 岁之间的学生信息
db.students.find({"age": {"$gte": 19}, {"$lte": 20}}).pretty();
在进行逻辑运算的时候,$and 的连接是最容易的,因为只需要利用 “ , ” 分割若干个条件就可以了
范例:查询年龄不是 19 岁的学生信息
db.students.find({"age": {"$ne": 19}}).pretty();
范例:查询年龄大于 19 岁,或者成绩大于 90 分的学生信息
db.students.find(
{
"$or": [
{
"age": {"$gt": 19}
},
{
"score": {"$gt": 90}
}
]
}
).pretty();
范例:也可以进行或的求反操作
db.students.find(
{
"$nor": [
{
"age": {"$gt": 19}
},
{
"score": {"$gt": 90}
}
]
}
).pretty();
针对于或的操作可以实现一个求反的功能。
在这几个逻辑运算之中,与的连接最简单,而或的连接需要为数据设置数组的过滤条件
模运算(求模)
模的运算使用 "$mod" 来完成,
- 语法:
{$mod:[数字,余数]}
范例:求模(找到年龄是 20 余 0 的同学)db.students.find({"age": {"$mod": [20, 0]}}).pretty();
范围运算
只要是数据库,必须存在有 "$in"(在范围之中)、"$nin"(不在范围中)
范例:查询姓名是“张三”、“李四”、“王五”的信息
db.students.find({"name": {"$in": ["张三"、"李四"、"王五"]}}).pretty();
范例:不在范围的查询 ———— 查询姓名不是“张三”、“李四”、“王五”的信息
db.students.find({"name": {"$nin": ["张三"、"李四"、"王五"]}}).pretty();
在实际的工作之中,范围的操作很重要。
数组运算(数组查询)
首先在 MongoDB 里面是支持数组保存的,一旦支持了数组保存,就需要针对于数组的数据进行匹配。
范例:保存一部分的数组内容
db.students.insert({"name": "谷大神 - A", "sex": "男", "age": 18 "score": 89, "address": "海淀区", "course": ["语文", "数学"]});
db.students.insert({"name": "谷大神 - B", "sex": "男", "age": 18 "score": 89, "address": "海淀区", "course": ["语文", "数学", "英语"]});
db.students.insert({"name": "谷大神 - C", "sex": "男", "age": 18 "score": 89, "address": "海淀区", "course": ["政治"]});
此时的数据包含有数组内容,而后需要针对于数组数据进行判断,可以使用几个运算符:"$all" "$size" "$slice" "$elemMatch"
范例:查询同时参加语文和数学课程的学生
- 现在两个数组内容都需要保存,所以使用
{"$all", [内容1,内容2]}
db.students.find({"course": {"$all": ["语文", "数学"]}}).pretty();
现在所显示的学生信息里面包含语文和数学的内容信息,而如果差一个内容的都不会显示。
虽然 "$all" 计算可以用于数组上,但是也可以用于一个数据的匹配上
范例:查询地址是海淀区的学生
db.students.find({"address": {"$all": ["海淀区"]}}).pretty();
既然在集合里面保存的是数组信息,那么数组就可以利用索引操作,使用 "key.index" 的方式来定义索引
范例:查询数组中第二个内容(index = 1,索引下标从 0 开始)为数学的信息
db.students.find({"course.1": "数学"}}).pretty();
范例:要求查询出只参加两门课程的学生
db.students.find({"course": {"$size": 2}}).pretty();
发现在进行数据查询的时候只要是内容符合条件,数组的内容就全部显示出来了,但是现在希望可控制数组的返回的数量,那么可以使用 "$slice" 进行操作
范例:返回年龄为 19 岁所有学生的信息,但是要求只显示两门参加的课程
db.students.find({"age": 19}, {"course": {"$slice": 2}}).pretty();
现在只取得了前两门的信息,那么也可以设置负数,表示取得后两门的信息
db.students.find({"age": 19}, {"course": {"$slice": -2}}).pretty();
或者只是取出中间部分的信息
db.students.find({"age": 19}, {"course": {"$slice": [1, 1]}}).pretty();
在此时设置的两个数据里面第一个数据表示开始的索引,第二个数据表示截取的个数
嵌套元素查询(嵌套集合运算)
在 MongoDB 数据库里面每一个几何数据可以继续保持其它的集合数据,例如:有些学生需要保存家长信息
范例:增加数据
db.students.insert({"name": "周杰伦 - A", "sex": "男", "age": 18 "score": 89, "address": "海淀区", "course": ["语文", "数学"],
"parents": [
{"name": "周杰伦 - A(父亲)", "age": 48, "job": "工人"},
{"name": "周杰伦 - A(母亲)", "age": 44, "job": "职员"},
]
});
db.students.insert({"name": "周杰伦 - B", "sex": "男", "age": 19 "score": 89, "address": "海淀区", "course": ["语文", "数学", "英语"],
"parents": [
{"name": "周杰伦 - B(父亲)", "age": 52, "job": "处长"},
{"name": "周杰伦 - B(母亲)", "age": 45, "job": "局长"},
]
});
db.students.insert({"name": "周杰伦 - C", "sex": "男", "age": 20 "score": 89, "address": "海淀区", "course": ["政治"],
"parents": [
{"name": "周杰伦 - C(父亲)", "age": 50, "job": "司机"},
{"name": "周杰伦 - C(母亲)", "age": 48, "job": "老板"},
]
});
此时给出的内容是嵌套的集合,而这种集合的数据判断只能够通过 "$elemMatch" 完成
范例:查询出父母有人是局长,年龄大于19岁的学生的信息
db.students.find({"$and": [
{"age": {"$gte": 19}},
{"parents": {"$elemMatch": {"job": "局长"}}}
]}).pretty();
由于这种查询的时候条件比较麻烦,所以如果可能,尽量别搞这么复杂的数据结构组成。
成员是否存在查询(判断某个字段是否存在)
使用 "$exists" 可以判断某个字段是否存在,如果设置为true表示找的是存在,如果设置为false就表示不存在
范例:查询具有 "parents" 成员的数据
db.students.find({"parents": {"$exists": true}}).pretty();
范例:查询不具有 "course" 成员的数据
db.students.find({"course": {"$exists": false}}).pretty();
可以利用此类查询来进行一些不需要的数据的过滤
唯一索引
唯一索引的主要目的是用在某一个字段上,使该字段的内容不重复。
范例:创建一个唯一索引
db.students.ensureIndex({"name": 1}, {"unique": true}}).pretty();
在 name 字段上的内容绝对不允许重复
范例:在 students 集合里面增加重复的数据
db.students.insert({"name": "张三", "sex": "男", "age": 18 "score": 89, "address": "房山区", "course": ["化学"]});
此时除了 name 字段上的内容之外,返现所有的数据都不一样,但是由于在 name 字段上设置了唯一的索引,所有程序里面如果增加了重复内容,那么会出现以下的错误提示信息:E11000 duplicate key error index:mldn.students.$name_1 dup key:......
阿里云产品简介:云数据库... 可以使用 MongoDB
阿里云数据库体验:数据库...
========================================================================
关于启动 MongDB 的 mongod.exe 遇到闪退问题解决办法
在 cmd 命令窗口按照官方安装MongoDB时遇到 启动 mongod.exe 闪退的问题,解决办法:在你安装 MongDB 的盘的根目录下,创建一个 db文件夹。我的是在 c 盘下 ,切记要在根目录下,然后需要先配置一下你要存储数据的地址,打开 cmd 命令窗口,进入到MongoDB\bin 目录下 输入:mongod --dbpath c:/db --port=27001
会出现。
实践:
- 在 MongoDB 根目录也就是 mongodb-win32-x86_64-windows-4.4.2 所在目录
和 mongodb-win32-x86_64-windows-4.4.2\bin 目录下,启动服务器都成功了。
- 可以用相对路径 比如:在 \bin 目录下执行mongod --dbpath ../db --port=27001
- 网上说可以这样:带日志信息
mongod --dbpath ./db --dblog ./log/mongodb.log --port=27001
。
提示:Error parsing command line: unrecognised option '--dblog' (解析命令行时出错:无法识别的选项'--dblog')
注意红色箭头部分。连接成功后就可以去浏览器打开http://localhost:27001 如果看到
It looks like you are trying to access MongoDB over HTTP on the native driver port.
则已经连接成功了。