管道
- 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
- MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。
- 管道操作是可以重复的。
聚合管道操作
可参考菜鸟文档:菜鸟文档
命令 | 功能描述 |
$project | 指定输出文档里的字段. |
$match | 选择要处理的文档,与fine()类似。 |
$limit | 限制传递给下一步的文档数量。 |
$skip | 跳过一定数量的文档。 |
$unwind | 扩展数组,为每个数组入口生成一个输出文档。(把列表拆开) |
$group | 根据key来分组文档。 |
$sort | 排序文档。 |
$geoNear | 选择某个地理位置附近的的文档。 |
$out | 把管道的结果写入某个集合。 |
$redact | 控制特定数据的访问。 |
$lookup | 多表关联(3.2版本新增) |
$lookup
相当关系型数据库中多表关联查询
属性 | 作用 |
---|---|
from | 同一个数据库下等待被Join的集合。 |
localField | 源集合中的match值,如果输入的集合中,某文档没有 localField这个Key(Field),在处理的过程中,会默认为此文档含有 localField:null的键值对。 |
foreignField | 待Join的集合的match值,如果待Join的集合中,文档没有foreignField值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。 |
as | 为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉 |
// 管道是一个切片,里面可以放很多操作
db.collection.aggregate([{ $lookup: { from: "外键表",localField: "本表外键字段", foreignField: "外键表字段", as: "起别名" }
})
实操
- 准备表1:
- 准备表2:
- 查询:
unc main() {VulnInfo:=GetCollection("SVD_DATA","VulnInfo")cur,err:=VulnInfo.Aggregate(context.Background(),[]bson.M{// 外键查询{"$lookup":bson.M{"from":"VulnTags","localField":"tags","foreignField":"id","as":"vuln_tags",}},// 限制两个{"$limit":2,},// 不要_id{"$project":bson.M{"_id":false,},},},)if err!=nil{fmt.Println(err)}else{dic:=make(map[string]interface{})for cur.Next(context.TODO()){err:=cur.Decode(dic)if err!=nil{fmt.Println(err)}else{fmt.Println(dic)}}}
}
结果:
无论是某站视频还是某些机构的文档,都没有聚合和管道的讲解,导致我这个自学菜鸟一直都是find
->for
->find
->append
手动查询两次,再拼接返回值,坑爹呢这是!!!