Обновить отдельный элемент в массиве, где к любому элементу массива применяются несколько условий
У меня есть базовая модель мангуста с атрибутом instruments
который представляет массив. Поэтому он состоит из нескольких элементов, каждый из которых имеет следующие атрибуты: name
, counter
, Сам документ имеет автоматически сгенерированный _id
типа ObjectID
,
модель
var ParticipationSchema = new Schema({
instruments: [{
name: String,
counter: Number
}],
// etc.
},
{
timestamps: true
});
Я хотел бы сейчас изменить ровно 1 пункт в instruments
массив, только если он соответствует следующим требованиям:
- Идентификатор документа должен равняться
58f3c77d789330486ccadf40
instruments
-Предметыname
который должен быть изменен, должен равняться'instrument-1'
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.
больше информации:
Ссылка API на $elemMatch
Спасибо @VEERAM за то, что они указали, что такое поведение также задокументировано на домашней странице mongodb.