猫鼬保存空数组错误“ TypeError:无法读取null的属性'1'”

时间:2019-02-01 04:24:37

标签: javascript mongoose

我有一个定义如下的模式:

const userSchema = new Schema({
  ...
  surveys: [surveyKeySchema],
  ...
})

surveyKeySchema实际上是这样定义的子文档方案:

const surveyKeySchema = new Schema({
  slug: {
    type: String,
    required: 'Please supply a slug',
    unique: true,
    lowercase: true,
    trim: true
  },
  name: {
    type: String,
    required: 'Please supply a name',
    trim: true
  },
  responseCount: {
    type: Number,
    default: 0
  }
})

现在,只要我尝试修改用户对此数组以外的任何内容,一切都会正常。当实例化用户时,它也是完全可以的。我也可以在清空数组之前立即在代码中调用await user.save()

只要至少剩余1个元素,从调查中删除任何子文档也可以。

但是,当我尝试使用以下方法删除最终的子文档时:

      await user.surveys.id(sid).remove()
      await user.save()

我在.save()的{​​{1}}上遇到错误。我很困惑,在网上找不到任何东西,我想必须至少要有一个子文档才能显示?有什么方法可以消除这个问题,或者如果我的假设是错误的,我将如何解决这个问题?

提前谢谢!如果我缺少明显的东西,我深表歉意!

编辑:

我发现猫鼬的mongo错误处理程序实际上是在正则表达式中抛出该错误,该正则表达式用于解析错误消息。破解它以返回原始错误消息:

TypeError: Cannot read property '1' of null

根据此question,我尝试添加E11000 duplicate key error index: db.users.$surveys.slug_1 dup key: { : null } ,但这没有用。

1 个答案:

答案 0 :(得分:0)

对于其他遇到此问题的人,这是我所做的:

  1. 在第19行的node_modules/mongoose-mongodb-errors/lib/plugin.js中,添加一个简单的console.error(err.message),以便实际上可以获取输出,而不是正则表达式处理程序错误。

  2. 因为当您在Mongoose中保存一个空的子文档数组时,这等效于将子模式设置为null值,这意味着当Mongoose评估您的子文档集合的索引时,会将其评估为具有值每个属性的null。如果您要使用属性建立索引(即子文档架构中的属性之一上面带有unique: true),则这是一种违规行为,因为null值不能唯一,至少在Mongo世界中不是唯一的。要解决这个问题,您可以添加sparse: true

  3. 现有集合中的任何文档以及现有集合本身都会因索引更改而造成问题。您需要删除索引才能使其正常工作。我删除了整个收藏集,因为我还是不需要它。

这是我更新的架构:

const surveyKeySchema = new Schema({
  slug: {
    type: String,
    required: 'Please supply a slug',
    unique: true,
    lowercase: true,
    sparse: true,
    trim: true
  },
  name: {
    type: String,
    required: 'Please supply a name',
    trim: true
  },
  responseCount: {
    type: Number,
    default: 0
  }
})