Документ соответствия MongoDB, в котором внедренный документ (массив объектов) имеет (вложенное) поле массива, имеющее значение только один раз - PullRequest
1 голос
/ 05 мая 2020

У меня в базе данных есть следующая схема :

{
   _id: Number,
   reagents: [ //Array of objects (embedded) FIND IF certain tag in v_class occurred only once in array
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       },
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       },
       {
           _id: Number,
           v_class: Array, //A single array (string only): ['TEST','PREMIUM']
       }
   ],
   other_fields: other_values,
}

MongoPlayground

Вопрос в том:

Как найти только те документы, в которых поле reagents содержит только один элемент (реагент, встроенные документы), среди v_class поля массива содержится слово PREMIUM.

Итак, из выбранной выше коллекции я хочу иметь только документ с _id: 2, потому что это единственный документ, в котором поле reagents имеет ТОЛЬКО документ, где в поле с именем v_class слово PREMIUM встречается только один раз.

UPD : Я получил несколько простых результатов после этапа $group, MongoPlayground (после группы). Так что на данный момент мне все еще нужно найти документы, где v_class поле массива встречается PREMIUM значение ровно один раз в этом массиве

UPD2: У меня появилась новая версия. MongoPlayground . Этот запрос хорош, но он показывает все PREMIUM, за исключением того, что произошло только один раз.

Ответы [ 2 ]

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

Я нашел свой способ найти результат отдельно от Олега, но он был первым, поэтому я голосую за него и принимаю в качестве ответа его вариант.

Мой запрос имеет единственное отличие. Он возвращает сами исходные документы, а не только справочные поля.

Полный запрос:

db.collection.aggregate([
  {
    $match: {
      reagents: {
        $elemMatch: {
          _id: 12
        }
      }
    }
  },
  {
    $group: {
      _id: {
        v_class: "$reagents.v_class",
        recipe_id: "$_id"
      },
      data: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $unwind: "$_id.v_class"
  },
  {
    $match: {
      "_id.v_class": "PREMIUM"
    }
  },
  {
    $group: {
      _id: "$_id.recipe_id",
      count: {
        $sum: 1,

      },
      data: {
        "$first": "$data"
      }
    }
  },
  {
    $match: {
      count: 1
    }
  }
])

Он находит точный элемент в поле реагентов (Array) по идентификатору, и документ имеет Поле v_class (Array) проверяет, встречается ли значение / тег только один раз.

MongoPlayground

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

$sum требует числового значения c, чтобы иметь смысл.

После того, как вы получили сумму, дополнительный этап $match может сравнить ее с 1.

https://mongoplayground.net/p/TKQowD-vd0f

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...