首页

第7章 MongoDB的高级语法

关灯 护眼    字体:

上一章 目录 下一章




MongoDB除了有简单的按键值查询外,还有不少高级查询方式,可以实现更加强大的数据查询功能。MongoDB的聚合查询功能,还能在查询的同时对数据进行处理,从而大大提高数据的处理效率。



7.1  AND和OR操作


在实际情况中,查询条件往往不止一条,这些条件可能需要同时满足,也可能需要从多个条件中任选其一。此时,就需要联合多个查询条件。



7.1.1  实例13:查询同时符合两个条件的人(AND操作)


在使用MongoDB查询时,对同一条记录常常会有多个判断逻辑。

实例描述

假设,数据集example_data_1如图7-1所示。

在这个数据集中,每一行表示一个人的信息,包括年龄(age)、工资(salary)和性别(sex),“id”不重复。

(1)使用隐式操作查询同时满足两个条件(age大于20,sex为“男”)的数据。

(2)使用显式AND操作查询所有年龄大于20且性别为“男”的数据。

(3)混合使用显式AND操作与隐式AND操作查询所有年龄大于20,性别为“男”,并且id小于10的数据。

图7-1  数据集example_data_1

1.隐式AND操作

现在要查询所有age大于20并且sex为“男”的数据。

可以构造以下这样一个查询语句:

对age与sex这两个字段的查询条件需要同时满足。

“同时满足”在逻辑上叫作“与(AND)”。

对于查询语句:

没有出现AND这个关键字,却能表达出“与”的关系,因此称为“隐式AND操作(implicit  AND  operation)”。

2.显式AND操作

MongoDB也有“显式AND操作(explicit  AND  operation)”。

显式AND操作的语法为:

本质上,这种写法和基础部分的查询条件是一致的,只不过基础部分的Key是各个字段名,而这里的Key是“$and”这样一个关键字,并且Value是一个列表,而列表中是很多个字典。每一个字典的写法和基础部分的“find”对应的第1个参数完全相同。

例如,查询所有年龄大于20且性别为“男”的数据。

使用显式AND操作的写法为:

显式AND操作的运行效果如图7-2所示。返回结果和隐式AND操作完全一致。

图7-2  使用显式AND操作

提示:

随着查询的条件越来越复杂,MongoDB查询语句中的括号会越来越多,因此要养成先把括号闭合,再填写里面内容的习惯。这样才不容易漏掉括号的后半部分,也不会把大括号中括号小括号的后半部分顺序搞错。

例如:

db.getCollection('example_data_1').find({'$and':  [{'age':  {'$gt':  20}},  {'sex':  ’男’}]})

应这样写:

(1)写db.getCollection('example_data_1').find())。

(2)用键盘方向键移动光标到find括号的中间,把大括号的左右部分写完。

(3)用键盘方向键将光标移动到大括号中间,写’$and':  []。

(4)用键盘方向键把光标移动到中括号里,写具体的每一个查询表达式。

3.显式AND操作和隐式AND操作混用

显式AND操作和隐式AND操作可以混合使用。

例如,查询所有年龄大于20,性别为“男”,并且id小于10的数据。

可以混合使用显式AND操作与隐式AND操作。具体代码如下:

查询结果如图7-3所示。

图7-3  混合使用显式AND操作与隐式AND操作

虽然MongoDB可以混合使用显式AND操作与隐式AND操作,但明显直接写为隐式AND操作会更简单易懂。

所有隐式AND操作都可以改写为显式AND操作。但反之不行,有一些显式AND操作不能改写为隐式AND操作。具体例子见7.1.2中的2.小标题。



7.1.2  实例14:查询只符合其中任一条件的人(OR操作)


实例描述

对于example_data_1数据集:

(1)查找所有年龄(age)大于28岁的数据,或者工资(salary)大于9900的数据。

(2)查询同时满足以下两个要求的数据:

●  age大于28,或者salary大于9900。

●  sex为“男”,或者id小于20。

(3)使用一条语句查询符合下面四种情况的所有数据:

●  age大于28的男性。

●  age大于28且id小于20的女性。

●  salary大于9900的男性。

●  salary大于9900且id小于20的女性。

在某些时候,多个查询条件只需要满足一个就可以了。这种情况有两种处理方式:

●  按照优先级依次把每一个查询条件带入到  MongoDB  中执行,如果有结果就使用结果,如果没有结果就换下一个查询条件。

●  使用“或(OR)”操作。

1.显式OR操作举例

OR操作与显式AND操作的格式完全一样,只需要把关键字“$and”换成“$or”即可。

具体语法如下:

collection.find({'$or':  [字典1,  字典2,  字典3,  ……,  字典n]})

OR操作会自动按顺序去检查每一个条件,直到某一个查询条件找到至少一条数据为止。
查询语句可以写为:

查询结果如图7-4所示。

图7-4  age大于28或者salary大于9900

从图7-4可以看出,对于每一行数据:

●  如果age大于28,那么salary的值是多少都无所谓。

●  如果age小于等于28,那么必有salary大于9900。

MongoDB在执行OR操作时会遵循一个“短路原则”:只要前面的条件满足了,那后面的条件就直接跳过。

如果age大于28,那就不需要去检查salary的值是多少。只有在age不满足查询条件时,才会去检查salary的值。

提示:

OR操作一定是显式的,不存在隐式的OR操作。

2.不能写成隐式的AND操作的举例

在7.1.1小节的最后提到,某些显式的AND操作不能写成隐式的AND操作,这里举一个例子。

这个查询其实是一个AND操作内部套两个OR操作。

查询语句见代码7-1。

代码7-1  不能写成隐式AND操作的例子

查询结果如图7-5所示。

图7-5  一个AND操作内部包含多个OR操作

对于这种查询条件,是没有办法写成隐式AND操作的。

提示:

对于复杂的查询条件,使用换行和缩进可以让代码看起来更清晰易懂。



7.1.3  实例15:用Python实现MongoDB的AND与OR操作


实例描述

使用Python操作MongoDB,查询数据集example_data_1的数据,只查询一次就找到符合下面四种情况的所有数据:

(1)age大于28的男性。

(2)age大于28并且id小于20的女性。

(3)salary大于9900的男性。

(4)salary大于9900且id小于20的女性。

Python中的显式AND操作与OR操作写法,与MongoDB中的写法完全一样。

下面用Python来实现7.1.2小节中的一个AND操作套两个OR操作。代码如下:

代码7-2  在Python中实现显式AND操作与OR操作

查询结果如图7-6所示。

图7-6  显式AND操作与OR操作在Python中的写法




上一章 目录 下一章