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

У меня есть базовая модель мангуста с атрибутом instruments который представляет массив. Поэтому он состоит из нескольких элементов, каждый из которых имеет следующие атрибуты: name, counter, Сам документ имеет автоматически сгенерированный _id типа ObjectID,

модель

var ParticipationSchema = new Schema({
    instruments: [{
      name: String,
      counter: Number
    }],
// etc.
},
{
    timestamps: true
});

Я хотел бы сейчас изменить ровно 1 пункт в instruments массив, только если он соответствует следующим требованиям:

  1. Идентификатор документа должен равняться 58f3c77d789330486ccadf40
  2. instruments-Предметы name который должен быть изменен, должен равняться 'instrument-1'
  3. instrument-Предметы counter должен быть ниже чем 3

запрос

let someId = '58f3c77d789330486ccadf40';
let instrumentName = 'instrument-1'
let counter = 3;

Participation.update(
{
    $and: [          
      { _id: mongoose.Types.ObjectId(someId) },
      { 'instruments.name': instrumentName },
      { 'instruments.counter': { $lt: counter } }
    ]},
    {
      $set: {
        'instruments.$.currentcounter' : counter
      }
    },
    (err, raw) => {
      // ERROR HANDLING
    }
});

Давайте предположим, что у меня есть 3 записи в instrumentsатрибута по:

"instruments": [
  {
    "name": "instrument-1",
    "counter": 2
  },
  {
    "name": "instrument-1",
    "counter": 2
  },
  {
    "name": "instrument-1",
    "counter": 2
  }
]

Желаемое поведение: изменить первый элемент counter приписывать 3, независимо от того, запускаете ли вы код обновления 1 раз, не выполняйте никаких действий при его запуске несколько раз.

Фактическое поведение:

  • это меняет 1-й элемент counter приписывать 3 при первом запуске
  • это меняет 2-й элемент counter приписывать 3 при запуске 2 раза
  • это изменяет 3-ий элемент counter приписывать 3 при запуске его в 3-й раз

1 ответ

Решение

Хотя запросы andЭд, они, кажется, не работают поэлементно. Чтобы решить проблему, $elemMatch может быть использован:

Participation.update({
         _id: mongoose.Types.ObjectId(someId),
         'instruments': {
            $elemMatch: {
              'name': instrumentName,
              'counter': { $lt: counter } }}
      },
      // etc.

больше информации:

Другие вопросы по тегам