如何在猫鼬中使用更新查询来更新文档?

时间:2019-11-22 14:39:13

标签: node.js mongodb mongoose

这是我在帖子模型中使用的注释密钥对:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const postSchema = new Schema({
user:{
    type:Schema.Types.ObjectId,
 //   required:true,
    refPath:'onModel'
},
onModel:{
    type:String,
    enum:['Doctor','Patient']
},
text:{
    type:String,
    required:true
},
comments:[{
    user:{
        type:Schema.Types.ObjectId,
        refPath:'onModel'

    },
    reply:{
        type:String
    },
    date:{
        type:Date,
        default:Date.now
    }
}],
likes:[{
    user: {
        type: Schema.Types.ObjectId,
        ref: 'Patient'
    }
}]
})

module.exports= post = mongoose.model('post', postSchema);

当我尝试通过运行以下代码将对象推到likes数组时,它失败。过滤器部分工作正常,但更新部分出现了一些问题,最终导致执行catch块。

Post.updateOne({ _id: req.params.postid, "likes": { $ne : { user: 
authorizedData.jwt_payload.patient._id }}},
    { "$set" : { "likes.$.user": "authorizedData.jwt_payload.patient._id" 
}})
    .then(re => res.json(re))
    .catch(err => res.json("already liked")) 

将非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

尝试使用$push聚合,该聚合用于将对象推入mongoDB中的内部数组。您的更新查询应类似于以下内容:

Post.updateOne({ _id: req.params.postid, "likes": { $ne : { user: 
authorizedData.jwt_payload.patient._id }}},
    { "$push" : { "likes": authorizedData.jwt_payload.patient._id
}})
    .then(re => res.json(re))
    .catch(err => res.json("already liked")) 

答案 1 :(得分:0)

请进行以下更改:

const mongoose = require('mongoose');

const patientObjectID = mongoose.Types.ObjectId(authorizedData.jwt_payload.patient._id);
Post.updateOne({
    _id: req.params.postid,
    'likes.user': {
        $ne:
            patientObjectID
    }
},
{ $push: { likes: { user: patientObjectID } } 
}).then(re => res.json(re)).catch(err => res.json("already liked"))

需要完成更改,所以当您拥有这样的架构时:

likes: [{
    user: {
        type: Schema.Types.ObjectId,
        ref: 'Patient'
    }
}]
  1. 您需要将ObjectId()传递给用户字段,而不是字符串,因此 首先,我们将字符串转换为ObjectId()并将其传递给查询。

  2. $set也用于 更新现有文件或在文档中插入新字段,但是当您要推送时 新值到文档中的数组字段,则需要使用 $push(这似乎是对字段的正常更新操作,但是这里我们不是要替换likes数组,而是要向其中添加更多元素-尽管是另一种更新,所以这就是为什么我们需要使用$push)。

  3. 就像您已经在下面的过滤器中一样,我们只是在$push假设我们要推送的内容不是重复项,而是以另一种方式可以盲目使用$addToSet来执行相同,而不必使用以下过滤条件:

    "likes": {
        $ne: {
            user:
                patientObjectID
        }
    }
    
  4. 关于$(update)的问题,为什么它不起作用?这应该用于更新数组中的元素,它有助于基于过滤条件更新数组中的第一个匹配元素,但是您在这里要做的是添加更多元素,但不更新{{1}中的现有元素}数组。

  5. 在这里您不应该在catch块中发送“已经喜欢的”,它应该是针对实际错误的自定义错误,在likes中,您需要检查更新操作的写入结果是否需要任何更新发送添加的用户,否则,您需要发送“已经喜欢”。

希望这可以解决您的所有问题:-)

相关问题