1

I am using golang as a backend with mongodb

My Collections are

**department**
    {
     dept_id:1,
     dept_name:'CSE',
     dept_overview:'overview'
    }
   ................

**employee**
    {
    emp_id:1,
    emp_name:'abc',
    qualification:'PHD',
    emp_dept:'CSE',
    city:'xyz'
    }
    {
    emp_id:2,
    emp_name:'xyz',
    qualification:'PHD',
    emp_dept:['CSE','ME'],
    city:'xyz',
    status:1
    }
    ..........

Below is my Go code using pipeline

 var conditionParam []bson.M
        if city == "" {
            conditionParam = []bson.M{
                bson.M{"$eq": []string{"$$element.qualification", "PHD"}},
                bson.M{"$in": []interface{}{"$$element.emp_dept", ["CSE"]}},
                bson.M{"$or": []interface{}{"$$element.emp_dept", "CSE"}},
                bson.M{"$eq": []string{"$$element.city", "xyz"}},
                bson.M{"$or": []interface{}{"$exists", []interface{}{"$$element.status", false}}},
                bson.M{"$or": []interface{}{"$$element.status", 1}}, 
            }
    } else if(){
    --------------------
}

matchStage:=bson.M{"$match":bson.M{'dept_id':1}}
lookupStage:=bson.M{"$lookup": bson.M{
    "from":         "employee",
    "localField":   "dept_name",
    "foreignField": "emp_dept",
    "as":           "result_list",
}}
    pipeline := getCollection.Pipe([]bson.M{
            matchStage,
            lookupStage,
            {"$addFields": bson.M{
                "result_list": bson.M{
                    "$filter": bson.M{
                        "input": "$result_list",
                        "as":    "element",
                        "cond": bson.M{
                            "$and": conditionParam,
                        },
                    },
                },
            }},
        })

In my collection some of data stored in string for emp_dept and some of the data stored in string slice. So I am using $in for comparing slice values and $or for string values for emp_dept.$in operator working for database string values but is not working for comparing emp_dept database values in slice. How we can return both values for slice and string for this particular key of mongodb collection.

1 Answer 1

1

The problem I understood is, you need to filter the array by $result_list.emp_dept which is in two different type that are string and array. You can use $type to check whether it's an array or string. If the scenario is correct, the following query works fine. Since you have written the pipeline in Go, I hope you can convert the following query to Go. Bcs I'm not a Go developer.

[
  {
    "$lookup": {
      "from": "employee",
      "localField": "dept_name",
      "foreignField": "emp_dept",
      "as": "result_list"
    }
  },
  {
    $addFields: {
      "result_list": {
        $filter: {
          input: "$result_list",
          cond: {
            $cond: [
              {
                $eq: [ { $type: "$$this.emp_dept" }, "string" ]
              },
              { // if the type is string
                $and: [
                  {
                    $eq: [ "CSE", "$$this.emp_dept" ]
                  },
                  {
                    $eq: [ "$$this.qualification", "PHD" ]
                  },
                  {
                    $eq: [ "$$this.city", "xyz" ]
                  }
                  // Other comparison
                ]
              },
              {  // if the type is NOT string
                $and: [
                  {
                    $in: [ "CSE", "$$this.emp_dept" ]
                  },
                  {
                    $eq: [ "$$this.qualification", "PHD" ]
                  },
                  {
                    $eq: [ "$$this.city", "xyz" ]
                  }
                  // Other comparison
                ]
              }
            ]
          }
        }
      }
    }
  }
]

Working Mongo playground

Sign up to request clarification or add additional context in comments.

6 Comments

can we check type inside $and then use $eq and $in accordingly for emp_dept only because I have no of parameters for comparison. like if type=='string' then $eq else $in
Of course yes, You can check $eq and $in another stage
I want to use only one $and and compare type for dept inside it without effecting other elements but I did not understand how to do it?
$varman where to compare the other element as $cond takes only 3 arguments?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.