这篇说说mongodb的聚合
一:mongodb中有很多聚合框架,从而实现文档的变换和组合,主要有一下构件
构件类别 操作符
筛选(filtering) $match
投射(projecting) $project
分组(grouping $group
排序(sorting) $sort
限制(limiting) $limit
跳过(skipping) $skip
如果需要聚合数据,那么要使用aggregate方法
db.collection.aggregate(聚合条件);
单个操作,传入一个json对象作为集合条件,如
db.users.aggregate({
$project:{
_id:0,
name:1,
}
})
如果需要多个操作符,传入一个数组作为条件,如
db.users.aggregate([
{ $skip : 5 },
{ $project:{ _id:0, name:1, } }
])
1.1:$match匹配
$match用于对文档集合进行筛选,之后就可以在筛选得到的文档子集上做聚合。
例如,如果想对北京(简写BJ)的用户做统计,就可以使用{$match:{"area":"BJ"}}。"$match"可以使用所有常规的查询操作符("$gt"、"$lt"、"$in"等)。有一个里外需要注意:不能在"$match"中使用地理空间操作符。
通常,在实际使用中应该尽可能将"$match"放在管道的前面位置。这样做有两个好处:
一是可以快速将不需要的文档过滤掉,以减少管道的工作量;
二是如果在投射和分组之前执行"$match",查询可以使用索引。
1.2:$project投射
相对于“普通”的查询而言,管道中的投射操作更加强大。使用"$project"可以从子文档中提取字段,可以重命名字段,还可以在这些字段上进行一些有意思的操作。
最简单的一个"$project"操作是从文档中选择想要的字段。可以指定包含或者不包含一个字段,它的语法和查询中的第二个参数类似。如果在原来的集合上执行下面的代码,返回的结果文档中只包含一个"author"字段。
db.articles.aggregate({"$project":{"author":1,"_id":0})
默认情况下,如果文档中存在"_id"字段,这个字段就会被返回。
赶快亲自动手敲下,看看运行结果。
也可以将投射过的字段进行重命名。例如,可以将每个用户文档的"_id"在返回结果中重命名为"userId":
db.articles.aggregate({"$project":{"userId":"$_id","_id":0}});
这里的"$fieldname"语法是为了在聚合框架中引用fieldname字段(上面的例子中是"_id")的值。例如,"$age"会被替换为"age"字段的内容(可能是数值,可能是字符串),"$tag.3"会被替换为tags数组中的第4个元素。所以,上面例子中的"$_id"会被替换为进入管道的每个文档的"_id"字段的值。
注意,必须明确指定将"_id"排除,否则这个字段的值会被返回两次:一次标记为"userId",一次被标记为"_id"。可以使用这种技术生成字段的多个副本,以便在之后"$group"中使用。
继续学习
1.3:$group分组
$group操作可以将文档依据特定字段的不同值进行分组。举例:
如果有一个学生集合,希望按照分数等级将学生分为多个组,可以根据"grade"字段进行分组。
如果选定了需要进行分组的字段,就可以将选定的字段传递给"$group"函数的"_id"字段。对于上面的例子,相应代码如下:
{"$group":{"_id":"$grade"}}
例如,学生分数等