1
{
   "attributes" : [
                    {
                      "dept" : "accounts",
                      "location" : "onshore"
                    },
                    {
                      "dept" : "HR",
                      "location" : "offshore"
                    },
                    {
                      "dept" : "technology"
                      "location": "NL"
                    } 
                 ]
},
{
   "attributes" : [
                    {
                      "dept" : "accounts",
                      "location" : "onshore"
                    },
                    {
                      "dept" : "technology"
                      "location": "London"
                    } 
                 ]
},
{
   "attributes" : [
                    {
                      "dept" : "accounts",
                      "location" : "onshore"
                    },
                    {
                      "dept" : "HR"
                      "location": "London"
                    } 
                 ]
}

I want to get those documents where attributes array has dept :technology with location NOTequal to london or the attributes array does not have field dept :technology. So the final output will be like below:

{
   "attributes" : [
                    {
                      "dept" : "accounts",
                      "location" : "onshore"
                    },
                    {
                      "dept" : "HR",
                      "location" : "offshore"
                    },
                    {
                      "dept" : "technology"
                      "location": "NL"
                    } 
                 ]
},
{
   "attributes" : [
                    {
                      "dept" : "accounts",
                      "location" : "onshore"
                    },
                    {
                      "dept" : "HR"
                      "location": "London"
                    } 
                 ]
}

I have tried this solution but it gives me all the documents:

{
                                "attributes": {
                                    "$elemMatch": {
                                        "$or": [
                                            {
                                                "dept": {
                                                    "$nin": ["technology"]
                                                }
                                            },
                                            {
                                                "$and": [
                                                    {
                                                        "dept": "technology"
                                                    },
                                                    {
                                                        "location": {"$ne" : "London"}
                                                    }
                                                ]
                                            }
                                        ]
                                    }
                                }
                            }
1

1 Answer 1

1

Since $elemMatch evaluates each item of the array, we cannot use $nin or $ne operators if the condition is only to negate the boolean expression.

Instead, we should use the $not to performs a logical NOT operation on the specified < operator-expression >.

Try this one:

db.collection.find({
  "$or": [
    {
      "attributes": {
        $not: {
          "$elemMatch": {
            dept: "technology"
          }
        }
      }
    },
    {
      "attributes": {
        "$elemMatch": {
          dept: "technology",
          location: {
            $ne: "London"
          }
        }
      }
    }
  ]
})

MongoPlayground

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

Comments

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.