管道
- 管道在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
手动查询两次,再拼接返回值,坑爹呢这是!!!