使用Mongoose ArrayFilters更新嵌套子文档时出错

时间:2019-05-14 09:28:12

标签: javascript node.js mongodb express mongoose

我有一个Mongoose集合,我想更新它的嵌套子文档。

基本设置是这样

  • 父条目(地图)
  • 其中包含一系列子项(阶段)
  • 每个孩子由一个或多个孙子(步骤)组成。

我希望能够找到一个孙子并对其进行更新。我的方法是找到包含孙子的父项(地图),然后对其进行更新。

这些是我的简化模式:

const phaseSchema = new mongoose.Schema(
  {
    name: String,
    color: String,
    steps: [
      new mongoose.Schema(
        {
          name: String,
          body: String,
          entry: {
            type: mongoose.SchemaTypes.ObjectId,
            ref: 'entry',
            default: null
          }
        },
        { timestamps: false }
      )
    ]
  },
  { timestamps: false, _id: true }
)

const mapSchema = new mongoose.Schema(
  {
    name: String,
    phases: [phaseSchema]
  },
  { timestamps: false }
)

export const Map = mongoose.model('map', mapSchema)

我正在尝试使用ArrayFilters查找和更新子文档,但是没有运气:

req.body = {
    map_id: 'some_mongoose_id',
    step_id: 'some_other_mongoose_id'
}
const newEntryId = 'a_new_mongoose_id'

// Find the parent (Map) and update it
const UpdatedMap = await Map.update(
    { _id: req.body.map_id }, 
    {
        $set: {
          'phases.$[i].steps.$[j].entry': mongoose.Types.ObjectId(newEntryId)
        }
    },
    {
        arrayFilters: [
            {
                'i.steps._id': mongoose.Types.ObjectId(req.body.step_id)
            },
            {
                'j._id:': mongoose.Types.ObjectId(req.body.step_id)
            }
        ]
    }
)

这将引发以下错误:

  

错误:在架构中找不到路径“ phases.0.steps.0._id:”

巧合的是,我要更新的阶段和步骤都位于索引0。

如果我换出arrayFilters并对索引进行硬编码(如$set: {'phases.0.steps.0.entry': mongoose.Types.ObjectId(newEntryId)'}这样,它将起作用。

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

i是导致错误的原因,并且也是多余的。没有它,嵌套的arrayFilter将按要求工作。

const UpdatedMap = await Map.update(
    { _id: req.body.map_id }, 
    {
        $set: {
          'phases.steps.$[j].entry': mongoose.Types.ObjectId(newEntryId)
        }
    },
    {
        arrayFilters: [
            {
                'j._id:': mongoose.Types.ObjectId(req.body.step_id)
            }
        ]
    }
)