聚合管道操作
聚合管道操作主要包含下面几个部分:
命令 | 功能描述 |
---|---|
$project | 指定输出文档里的字段. |
$match | 选择要处理的文档,与fine()类似。 |
$limit | 限制传递给下一步的文档数量。 |
$skip | 跳过一定数量的文档。 |
$unwind | 扩展数组,为每个数组入口生成一个输出文档。 |
$group | 根据key来分组文档。 |
$sort | 排序文档。 |
$geoNear | 选择某个地理位置附近的的文档。 |
$out | 把管道的结果写入某个集合。 |
$redact | 控制特定数据的访问。 |
$lookup | 多表关联(3.2版本新增) |
语法
是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(户名可根据需要命名新key的名字 )。数组列存放的数据是来自被Join集合的适配文档,如果没有,集合为空(即 为[ ])
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}
语法值 | 解释说明 |
---|---|
from |
同一个数据库下等待被Join的集合。 |
localField |
源集合中的match值,如果输入的集合中,某文档没有 localField这个Key(Field),在处理的过程中,会默认为此文档含有 localField:null的键值对。 |
foreignField |
待Join的集合的match值,如果待Join的集合中,文档没有foreignField 值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。 |
as |
为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉, |
其语法功能类似于下面的伪SQL语句:
SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT *
FROM <collection to join>
WHERE <foreignField>= <collection.localField>);
实例
这里有一个PROJECT项目表和STAR收藏表,用户收藏项目后,会向收藏表里记录所属项目的id,字段为sid.
现有需求,查询wenjie
用户收藏项目名包含测试
的所有项目,查询语句如下:(status和sType为其他业务字段,这里不用关心)
db.STAR.aggregate([
{$match:{owner:"wenjie",status:0,sType:1}},
{$lookup:{from:"PROJECT",localField:"sid",foreignField:"_id",as:"target"}},
{$unwind: "$target"},
{$project:{‘sType‘:1,‘target._id‘:1,‘target.name‘:1,‘_id‘:1,‘sid‘:1}},
{$match:{‘target.name‘:/测试/}}
])
查询结果如下: