更新数组中的单个项目,其中多个条件适用于任何数组项

update single item within array where multiple conditions apply to any array item

我有一个基本的猫鼬模型,其属性 instruments 代表一个数组。因此它由多个项目组成,每个项目都具有以下属性:namecounter。文档本身有一个自动生成的 _id 类型 ObjectID.

型号

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

我现在只想更改 instruments 数组中的 1 个项目,前提是它符合以下要求:

  1. 文档 ID 必须等于 58f3c77d789330486ccadf40
  2. 应更改的 instruments-item 的 name 必须等于 'instrument-1'
  3. instrument-item 的 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
    }
});

假设我在 instruments- 属性中有 3 个条目:

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

期望的行为: 将第一个元素的 counter 属性更改为 3,无论如何,当 运行 更新代码 1 次时,当 运行 多次时不做任何动作。

实际行为:

虽然查询是 anded,但它们似乎不是 运行 元素明智的。要解决此问题,可以使用 $elemMatch

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

更多信息: