Javascript Mongoose保存空数组错误“;TypeError:无法读取属性';1';“无效”的定义;
我有一个这样定义的模式:Javascript Mongoose保存空数组错误“;TypeError:无法读取属性';1';“无效”的定义;,javascript,mongoose,Javascript,Mongoose,我有一个这样定义的模式: const userSchema = new Schema({ ... surveys: [surveyKeySchema], ... }) const surveyKeySchema = new Schema({ slug: { type: String, required: 'Please supply a slug', unique: true, lowercase: true, trim: true
const userSchema = new Schema({
...
surveys: [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
}
})
其中,surveyKeySchema
实际上是这样定义的子文档方案:
const userSchema = new Schema({
...
surveys: [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
}
})
现在,每当我尝试修改用户上除此数组以外的任何内容时,一切都会正常进行。当实例化用户时,它也是完全正确的。在清空数组之前,我还可以在代码中调用wait user.save()
当我从调查中删除任何子文档时也可以,只要至少还有1个元素
但是,当我尝试使用以下命令删除最终子文档时:
await user.surveys.id(sid).remove()
await user.save()
我在.save()
上得到一个错误,它只是类型错误:无法读取null的属性“1”。我很困惑,在网上找不到关于这个的任何信息,我想它必须至少有一个子文档存在?有没有办法消除这个问题,或者如果我的假设是错误的,我将如何着手解决这个问题
提前谢谢!如果我遗漏了一些明显的东西,我向你道歉
编辑:
我发现mongoose的mongo错误处理程序实际上是在一个用于解析错误消息的正则表达式中抛出这个。对其进行黑客攻击以返回原始错误消息:
E11000 duplicate key error index: db.users.$surveys.slug_1 dup key: { : null }
根据这一点,我尝试添加了sparse:true
,但没有成功。对于其他有此问题的人,我所做的如下:
在第19行的node\u modules/mongoose mongodb errors/lib/plugin.js
中,添加一个简单的console.error(err.message)
以便您可以实际获得输出,而不是regex处理程序错误
因为在Mongoose中保存子文档的空数组相当于将子模式的值设置为null,这意味着当Mongoose评估子文档集合的索引时,它将评估每个属性的值为null。如果您使用属性(即子文档架构中的一个属性上有unique:true
)进行索引,则这是一种违规行为,因为空值不能是唯一的,至少在Mongo world中不能。要解决这个问题,您可以添加sparse:true
现有集合中的任何文档以及现有集合本身都将产生一个问题,即现在索引已更改。您需要删除索引才能使其工作。我放弃了整个收藏,因为我根本不需要它
以下是我更新的模式:
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
}
})