首页

7.3MongoDB的聚合查询

关灯 护眼    字体:

上一章 章节列表 下一页


到目前为止,MongoDB只是作为一个保存数据的角色:开发者把数据保存到其中,等需要使用时,按照一定规则把数据提取出来,然后用Python或者Excel再对数据进行进一步处理。

但实际上,MongoDB 自带了一个聚合(Aggregation)功能。使用聚合功能,可以直接让MongoDB来处理数据。聚合功能可以把数据像放入传送带一样,先把原始数据按照一定的规则进行筛选处理,然后通过多个不同的数据处理阶段来处理数据,最终输出一个汇总的结果。

用一个形象的例子来说明什么是聚合操作。假设苹果树上的很多苹果就是“原始数据”,而“吃”这个动作就是“输出”。那么苹果从树上进入人的嘴巴,可能会有如图7-17所示的几种不同的情况。

图7-17 苹果入口的几种不同方式

图中的“筛选”“榨汁”“加入添加剂”“制作糖果”称为聚合操作的不同“阶段(Stage)”,前一个阶段的输出是后一个阶段的输入,通过接力的方式完成从原始数据到最终数据的转换。



7.3.1 聚合的基本语法


聚合操作的命令为“aggregate”,基本格式为:

聚合操作可以有0个、1个或者多个阶段。

如果有0个阶段,则查询命令写为:

collection.aggregate()

那么它的作用和“collection.find()”一样。请对比图7-18和图7-1。

图7-18 有0个阶段的aggregate作用和find()相同

如果聚合有至少一个阶段,那么每一个阶段都是一个字典。不同的阶段负责不同的事情,每一个阶段有一个关键字。有专门负责筛选数据的阶段“$match”,有专门负责字段相关的阶段“$project”,有专门负责数据分组的阶段“$group”等。聚合操作有几十个不同的阶段关键字,本书选择其中常用的一些来作讲解。



7.3.2 实例20:筛选数据


实例描述

从数据集example_data_1中,查询age大于等于27,且sex为“女”的所有记录。

一般情况下,并非所有的数据都需要被处理,因此大多数时候聚合的第一个阶段是数据筛选。就像“find()”一样,把某些满足条件的数据选出来以便后面做进一步处理。

数据筛选的关键字为“$match”,它的用法为:

例如,从example_data_1数据集中,查询age大于等于27,且sex为“女”的所有记录。聚合查询语句为:

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

图7-19 使用聚合来查询数据

从查询结果来看,这一条聚合查询语句的作用完全等同于:

db.getCollection('example_data_1').find({'age': {'$gte': 27}, 'sex': ’女’})

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

图7-20 使用find可以实现相同的效果

这两种写法,核心查询语句“{'age': {'$gte': 27}, 'sex': ’女’}”完全一样。

聚合查询操作中的,“{'$match': {和find完全一样的查询表达式}}”,“$match”作为一个字典的Key,字典的Value和“find()”第1个参数完全相同。“find()”第1个参数能怎么写,这里就能怎么写。

例如,查询所有age大于28或者sex为“男”的记录,聚合查询语句就可以写为:

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

图7-21 聚合查询的查询部分与“find()”第一个参数完全相同

从效果上看,使用聚合查询与直接使用“find()”效果完全相同,而使用聚合查询还要多敲几次键盘,那它的好处在哪里呢?

聚合操作的好处在于“组合”。接下来会讲到更多的聚合关键字,把这些关键字组合起来才能体现出聚合操作的强大。



7.3.3 实例21:筛选与修改字段


实例描述

对图7-1所示的数据集example_data_1,使用聚合操作实现以下功能:

(1)不返回_id字段,只返回age和sex字段。

(2)所有age大于28的记录,只返回age和sex。

(3)在$match返回的字段中,添加一个新的字段“hello”,值为“world”。

(4)在$match返回的字段中,添加一个新的字段“hello”,值复制age的值。

(5)在$match返回的字段中,把age的值修改为一个固定字符串。

(6)把user.name和user.user_id变成普通的字段并返回。

(7)在返回的数据中,添加一个字段“hello”,值为“$normalstring”,再添加一个字段“abcd”,值为1。

“$match”可以筛选出需要的记录,那么如果想只返回部分字段,又应该怎么做呢?这时就需要使用关键字“$project”。

1.返回部分字段

首先用“$project”来实现一个已经有的功能——只返回部分字段。格式如下:

这里的字段过滤语句与“find()”第2个参数完全相同,也是一个字典。字段名为Key,Value为1或者0(需要的字段Value为1,不需要的字段Value为0)。

例如,对于图7-1所示的数据集,不返回“_id”字段,只返回age和sex字段,则聚合语句如下:

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

结合“$match”实现“先筛选记录,再过滤字段”。例如,选择所有age大于28的记录,只返回age和sex,则聚合语句写为:

图7-22 只返回age和sex不返回“_id”

<
m.qiduwx.com提示您,本章没有阅读完,点击下一页进入下一页阅读!

上一章 章节列表 下一页