mongo的聚合查询引用了管道的概念,什么是管道呢,先看一下菜鸟教程上的描述
MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
其实就是将每一次表达式处理后的结果缓存起来,作为下一个表达式的文档结构,直到最后一个表达式处理后输出。可见它是单向的、有序的
具体的使用方法可以看菜鸟教程(懒死)
这里记录曾经使用过的部分API(防痴呆):(注:黄色标记的表示不属于管道方法)
api | 介绍 | 实例 |
$addFields | 添加一个新字段 |
|
$project | 过滤字段 |
|
$subtract | 两数相减,可用于判断大小 |
|
$filter | 从数组中筛选出符合条件的元素 | 看下文 |
$lookup | 跨表查询 | 看下文 |
注意事项:
1、$可以表示管道的方法名,也可以表示管道中的字段
2、$filter不是一个管道命令,无法单独使用,它可以配合$project方法使用,如下代码:
// 这个表达式的意思是,从arr字段(数组)筛选出值等于1的元素,塞入newArr方法中
db.collection.aggregate([
{
$project: { // 管道方法
newArr: { // 新字段名称,也可以和原来的字段arr同名
$filter: { // mongo方法,用户筛选出数组符合条件的元素
input: '$arr', // 需要过滤的数组字段
as: 'item', // 元素的变量名
cond: {$eq: ['$$item': 1] // $$item是元素的变量名,$eq是mongo方法,判断元素是否相等
}
}
}
}
])
3、$addToSet
和$push
的区别在于$addToSet
比$push
多了一个去重的功能,但在聚合分组($group
)查询里面,$push
会按照上个查询的结果顺序依次插入数组,而$addToSet
则会将顺序打乱(目前没有找到到排序规律),具体原因不明,猜测是和$addToSet
的去重有关。
4、$lookup
的具体使用看下列代码:
// 这个表达式的意思是查询collection2集合里id和collection1的id相等的文档,并将文档添加到docs2字段里
db.collection1.aggregate([
{
$lookup: { // 管道方法
from: 'collection2', // 联合查询的集合
localField: 'id', // 当前集合匹配的字段,
foreignField: 'id', // 目标集合(即collection2)匹配的字段
as: 'docs2' // 将跨表查询的文档插入到此处,此字段是数组类型
}
}
])