为了账号安全,请及时绑定邮箱和手机立即绑定

在 go mongodb 中的 From Table 上匹配阶段

在 go mongodb 中的 From Table 上匹配阶段

Go
胡子哥哥 2022-06-21 16:47:33
我的 mongodb 收藏employee{  _id:ObjectId(),  "emp_name":"qwert",  "emp_id":111,  "emp_dept":"XYZ"  "qualification":"PHD"}{_id:ObjectId(),  "emp_name":"asdfg",  "emp_id":121,  "emp_dept":"XYZ" "qualification":"MBA"}department{_id:ObjectId(),"dept_id":11,"dept_name":"XYZ","description":"decs",}我的 Go 代码是 type Employee struct {    EmployeeName  string             `json:"emp_name" bson:"emp_name"`    EmployeeID    int                `json:"emp_id" bson:"emp_id"`    EmployeeDept  string             `json:"emp_dept" bson:"emp_dept"`    EmpQualification string          `json:"qualification" bson:"quaification"`     EmpDepartment Department         `json:"department" bson:"department"` } type Department struct {    DepartmentID    int                `json:"dept_id" bson:"dept_id"`    DepartmentName  string             `json:"dept_name" bson:"dept_name"`     Description     string             `json:"description" bson:"description"`     EmployeeList    []Employee         `json:"employee_list" bson:"employee_list"`}collection := session.DB("db").C("department")pipeline := collection.Pipe([]bson.M{        {"$lookup": bson.M{        "from":         "employee",        "localField":   "dept_name",        "foreignField": "emp_dept",        "as":           "employee_list",    }},      {"$match": bson.M{        "qualification": "PHD",          }},    })err = pipeline.All(&departmentEmployees)它显示空结果我想从我的部门集合中获取所有部门,每个部门都有“PHD”资格的员工列表。我已将我的集合和结构上传为示例。如何在查找表中使用匹配字段。我想得到像{    dept_id:11,   dept_name:'XYZ'   description:'desc'   employee_list:[     {     emp_name:"qwerty"     emp_id:111,     qualification:'PHD'      }     {     emp_name:"asdfg"     emp_id:222,     qualification:'PHD'      }...]} {    dept_id:12,   dept_name:'ABC'   description:'descwe'   employee_list:[     {     emp_name:"bjgk"     emp_id:865,     qualification:'PHD'      }     {     emp_name:"hkj"     emp_id:967,     qualification:'PHD'      }...]}对于第一所大学,让所有员工获得博士学位,然后在第二所大学获得博士学位,依此类推。我很困惑我是否必须在查找中使用 group by in 从集合中?
查看完整描述

1 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

首先,您的Employee.EmpQualification字段标签中有错字:


EmpQualification string `json:"qualification" bson:"quaification"`

它应该是:


EmpQualification string `json:"qualification" bson:"qualification"`

接下来,当您将员工查找为 时employee_list,这将是结果中的一个新字段,因此qualification将引用员工的字段department而不是员工的字段。


既然employee_list是一个数组,你不能简单地匹配,你必须过滤数组,并用employee_list新的过滤数组替换。


最后,您可能希望排除没有任何具有“PHD”资格的员工的部门。


最终的聚合如下所示:


pipeline := collection.Pipe([]bson.M{

    {"$lookup": bson.M{

        "from":         "employee",

        "localField":   "dept_name",

        "foreignField": "emp_dept",

        "as":           "employee_list",

    }},

    {

        "$addFields": bson.M{

            "employee_list": bson.M{

                "$filter": bson.M{

                    "input": "$employee_list",

                    "as":    "emp",

                    "cond":  bson.M{

                        "$eq": []interface{}{"$$emp.qualification", "PHD"},

                    },

                },

            },

        },

    },

    {"$match": bson.M{

        "employee_list": bson.M{"$not": bson.M{"$size": 0}},

    }},

})

另请注意,上述聚合必须搜索所有部门及其员工。更好的方法是从员工开始,按资格筛选,然后按部门分组。


扩展第二种方法:一旦您拥有拥有 PHD 的员工,将员工分组emp_dept并聚集在 中employee_list,然后查找部门。然后你必须“构建”结果文档,即查找的部门必须是附加的emplyee_list(在阶段期间收集的$group)的“根”。


这就是它的样子:


pipeline := collection.Pipe([]bson.M{

    {"$match": bson.M{

        "qualification": "PHD",

    }},

    {"$group": bson.M{

        "_id":           "$emp_dept",

        "employee_list": bson.M{"$push": "$$ROOT"},

    }},

    {"$lookup": bson.M{

        "from":         "department",

        "localField":   "_id",

        "foreignField": "dept_name",

        "as":           "department",

    }},

    {"$unwind": "$department"},

    {"$replaceRoot": bson.M{

        "newRoot": bson.M{

            "$mergeObjects": []interface{}{

                "$department",

                bson.M{"employee_list": "$employee_list"},

            },

        },

    }},

})

第二种方法的优点是它只处理拥有 PHD 的员工(确保有一个索引),只加载拥有此类员工的部门。


另请注意,最好将部门 ID 存储在员工中而不是部门名称中,如果将来必须重命名部门,则只需在一个地方(在部门文档中)更改它。


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 103 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信