在mongodb中按索引删除时出现问题,无法将未定义或null转换为对象

时间:2019-10-24 08:55:53

标签: mongodb mongoose

我正在尝试通过索引从数组中删除一个项目(即一个对象)。在其他情况下,我可以实现此目标,但在这种情况下,它会抛出该错误。我在做什么错了?

架构

const activated =  Schema({
user:{type:String},
ts:{type:Date}
},{_id:false});

const pendientes = Schema({
testID:{type:Schema.ObjectId,ref:'test'},
enviadoPor:{type:String},
fechaEnvio:{type:Date,default:Date.now},

},{_id:false});

const realizados = Schema({
testID:{type:Schema.ObjectId,ref:'test'},
enviadoPor:{type:String},
fechaEnvio:{type:Date},
respuestas:{type:Schema.ObjectId,ref:'respuesta'},
fechaRealizacion:{type:Date,default:Date.now}
},{_id:false});


const pacienteSchema = Schema({
_id: { type: Schema.ObjectId, auto: true },
pName: { type: String },
pEmail: { type: String, unique: true },
pPassword: { type: String, default: 'Cambiame' },
pCodigo: { type: String },
pTestRealizados: { type: [realizados] },
pTestPendientes: { type: [pendientes] },
pMedicos:{type:[Schema.ObjectId],ref:'user'},
pRespuestas:{type:[Schema.ObjectId],ref:'respuesta'},
pFechaRegistro: { type: Date, default: Date.now },
pActivated:{type:activated}

}, { versionKey: false });

功能

exports.updatePTest = function (req, res) {
let pEmail = req.body.pEmail;
let tIndex = req.body.tIndex; // index that come from frontend
let parsedIndex = Number.parseInt(tIndex); // need to parse it to number
let pTestPendientes = `pTestPendientes.${tIndex}`; // Complete string with index (specific field)
let respuestaId = req.body.respuestaId;

Paciente.findOne({ pEmail: pEmail }, {
    'pTestPendientes': 1
}).then(result => {
    let i = parsedIndex;
    let item = result.pTestPendientes[i];
    Paciente.findOneAndUpdate({ pEmail: pEmail }, {
        '$push': {
            'pTestRealizados': {
                'testID': item.testID,
                'enviadoPor': item.enviadoPor,
                'fechaEnvio': item.fechaEnvio,
                'respuestas': respuestaId,
            },
            'pRespuestas': respuestaId
        }
    },{new:true}).exec().then(()=>{
        Paciente.findOneAndUpdate({ pEmail: pEmail }, {
            '$unset': {
                [pTestPendientes]: 1
            }
        }).then(()=>{                
           Paciente.findOneAndUpdate({ pEmail: pEmail }, {
                '$pull': {
                    'pTestPendientes': null
                }
            }).then(()=>{console.log('This then is not executed');}
            ).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); });
        }).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); });
    }).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); }); 
}).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); });
};

使用此功能,mongodb取消设置了我想要的项目(将其设置为null),但是它不执行功能的最后一部分($ pull)来删除null。 一些技巧?有什么想法吗? 谢谢

更新

非常感谢@OTZ,他发表的评论帮助我完成了我想做的事情,但是却产生了巨大的副作用。现在,我的应用程序无法识别已更新的文档。

exports.updatePTest = function (req, res) {
let pEmail = req.body.pEmail;
let tIndex = req.body.tIndex;
let parsedIndex = Number.parseInt(tIndex);
let pTestPendientes = `pTestPendientes.${tIndex}`;
let respuestaId = req.body.respuestaId;

Paciente.findOne({ pEmail: pEmail }, {
    'pTestPendientes': 1
}).then(result => {
    let i = parsedIndex;
    let item = result.pTestPendientes[i];
    Paciente.findOneAndUpdate({ pEmail: pEmail }, {
        '$push': {
            'pTestRealizados': {
                'testID': item.testID,
                'enviadoPor': item.enviadoPor,
                'fechaEnvio': item.fechaEnvio,
                'respuestas': respuestaId,
            },
            'pRespuestas': respuestaId
        }
    },{new:true}).exec().then(()=>{ //New code thx to @OTZ
       Paciente.findOne({pEmail:pEmail}).then(paciente=>{paciente._doc.pTestPendientes.splice(tIndex,1); 
        paciente.save().then(()=>{console.log('saved');
    }).catch(err=>{console.log(err);})}).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); }); 
    }).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); }); 
}).catch(err => { res.status(500).send({ accion: 'updatePTest', message: 'Error ' }); logger.error(err); });
};

paciente.save()是否有其他行为或更改了我的模型?有人可以解释吗?在mongo Compass中,文档完全按照需要的方式显示,但是就像模型中的某些内容一样,我看不到是错误的或消失了。我在登录页面上输入了正确的密码和电子邮件,然后返回401,我知道密码和电子邮件都可以。

一些提示?谢谢。

更新2 [已解决] [已计划]

好的,终于可以了!我的Paciente模式中有一个pacienteSchema.pre('save')函数。因此,当我执行@OTZ发布的save函数时,我正在对密码进行新的加密。我这样解决了:

pacienteSchema.pre('save', function (next) {
if (this.isModified('pPassword')===false) {
    next();
}else{
    this.pPassword = bcrypt.hashSync(this.pPassword, saltRounds);
    next();
}
  });

0 个答案:

没有答案