首页

7.2查询子文档或数组中的数据

关灯 护眼    字体:

上一章 目录 下一章




如果MongoDB的字段中包含子文档或者数组,则查询方式和查询普通的字段有一些区别。



7.2.1  认识嵌入式文档


MongoDB作为NoSQL,储存的数据可以是各种可以的格式。

例如,把下面这一段数据保存到MongoDB中:

导入以后得到的example_data_2数据集如图7-7所示。

图7-7  example_data_2数据集:字段中嵌套字典

在这个数据集中,“user”称为嵌入式文档(Embedded  Document),“user”下面的字段称为嵌套字段(Nested  Field)。

如要查询嵌套字段,则需要使用点号来指定具体的字段名,格式如下:

嵌入式文档名.嵌套字段名



7.2.2  实例16:嵌入式文档的应用


实例描述

对于数据集example_data_2,执行以下操作:

(1)查询user_id为102的数据。

(2)查询所有“followed”大于10的数据。

(3)查询数据,并只返回“name”和“user_id”这两个字段。

1.使用点号定位嵌套字段

例如,在数据集example_data_2中,查询user_id为102的数据。

使用点号定位到嵌套字段user中的子字段user_id为102的数据,语句为:

db.getCollection('example_data_2').find({'user.user_id':  102})

结果如图7-8所示。

图7-8  使用点号查询嵌入字段

嵌入字段只是定位的时候多了一步。除此之外,嵌入字段和普通字段没有区别。

例如,查询所有“followed”大于10的数据的语句如下:

db.getCollection('example_data_2').find({'user.followed':  {'$gt':  10}})

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

图7-9  查询“followed”大于10的数据

2.返回嵌套字段中的特定内容

如需要在返回的查询结果中只显示嵌入式文档中的部分内容,也可以使用点号来实现。例如只返回“name”和“user_id”这两个字段,那么查询语句见代码7-3。

代码7-3  使用$project关键字返回嵌套字段中的特定内容

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

图7-10  只返回嵌入式文档的部分信息

查询的结果还是一个嵌入式文档,但是只包含需要的字段。在学习了7.3节的内容以后,可以把嵌入式字段变为普通字段。

提示:

对于嵌套字段下面还有嵌入式文档的情况(类似于Python字典套字典),如要查询内层的字段,则继续使用点号即可。例如:

user.work.boss



7.2.3  认识数组字段


Python的列表被写入到MongoDB中就会变成数组(Array),要查询数组中的内容,又有一套自己的方法。有如下数据:

插入MongoDB后得到example_data_3数据集,如图7-11所示。

图7-11  example_data_3数据集

读数组的操作,无外乎以下几种情况:

(1)数组包含或者不包含某些数据。

(2)数组长度。

(3)数组中特定位置的数满足某些条件。



7.2.4  实例17:数组应用——查询数组包含与不包含“××”的数据


实例描述

在数据集example_data_3中进行如下查询:

(1)查询所有size包含M的记录。

(2)查询所有size不包含M的记录。

(3)查询price至少有一个元素在200~300范围中的记录。

1.查询数组包含与不包含数据

(1)查询数组包含数据。

要查出所有“size”包含“M”的数据,查询语句为:

db.getCollection('example_data_3').find({'size':  'M'})

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

图7-11  查出所有“size”包含“M”的数据

从图7-12可以看出,查询所有某个数组包含某个数据的记录,在写法上完全等同于“查询一个普通字段等于某个值的所有记录”。

(2)查询数组不含数据。

查询所有某个数组不包含某个数据的记录,写法如下:

db.getCollection('example_data_3').find({'size':  {'$ne':  'M'}})

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

图7-12  数组size不包含M的所有记录

2.数组中至少有一个元素在另一个范围空间内

查询所有满足要求的记录:这些记录中有一个数组,数组中至少有一个元素在某个范围内。写法和“查询某个范围内的普通字段”完全一样,例如:

db.getCollection('example_data_3').find({'price':  {'$lt':  300,  '$gte':  200}})

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

图7-13  price数组中至少有一个数据在200(含)~300之间



7.2.5  实例18:数组应用——根据数组长度查询数据


实例描述

从数据集example_data_3中查询所有price长度为2的记录。

根据数组的长度查询数据也非常简单,使用关键字“$size”。

例如,查询所有“price”字段长度为2的记录,查询语句为:

db.getCollection('example_data_3').find({'price':  {'$size':  2}})

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

图7-14  查询“price”长度为2的所有记录

提示:

“$size”只能查询具体某一个长度的数组,不能查询长度大于或小于某个值的数组。



7.2.6  实例19:数组应用——根据索引查询数据


实例描述

从数据集example_data_3中,查询所有满足以下条件的数据:

(1)所有size第1个数据为S的记录。

(2)price第1个数据大于500的所有记录。

1.根据数组索引查询数据

数组和列表一样,也有一个索引。通过这个索引能够定位到数组中的具体某个数据。

索引是从0开始的,索引为“0”表示数组中的第1个数据,索引为“1”表示数组中的第2个数据。根据索引查询某个值,也需要使用点号。

例如,查询所有“size”的第1个数据为“S”的记录,查询语句为:

db.getCollection('example_data_3').find({'size.0':  'S'})

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

图7-15  查询“size”第一个数据为“S”的所有记录

2.根据数组索引比较数据的大小

使用索引也可以比较大小。例如,查询“price”第1个数据大于500的所有记录:

db.getCollection('example_data_3').find({'price.0':  {'$gt':  500}})

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

图7-16  “price”第一个数据大于500的记录



7.2.7  Python操作嵌入式文档与数组字段


实例描述

在Python中操作嵌入式文档和数组字段,分别查询以下信息:

(1)查询所有size包含M的记录。

(2)查询price至少有一个元素在200~300范围中的记录。

(3)查询price有两个元素的记录。

(4)查询price索引为0的元素大于500的所有记录。

如果  MongoDB  的查询语句每一个关键字都使用了引号包起来,那么这些查询语句直接复制到Python中就可以使用。例如:

代码7-4  Python操作嵌入式文档和数组字段




上一章 目录 下一章