Критерии соответствия агрегации MongoDB, чтобы определить, существует ли поле со значением в массиве - PullRequest
1 голос
/ 05 мая 2020
{
   "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"
                    } 
                 ]
}

Я хочу получить те документы, в которых массив attributes имеет dept: technology с location НЕ равным london или массив attributes не имеет поле dept: technology. Таким образом, окончательный результат будет таким, как показано ниже:

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

Я пробовал это решение, но оно дает мне все документы:

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

1 Ответ

1 голос
/ 06 мая 2020

Поскольку $elemMatch оценивает каждый элемент массива, мы не можем использовать операторы $nin или $ne, если условие состоит только в том, чтобы отрицать логическое выражение.

Вместо этого мы должны использовать $ not для выполнения логической операции NOT над указанным <оператор-выражение> .

Попробуйте это:

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

MongoPlayground

...