如果我不指定要更新的字段,猫鼬findOneAndUpdate不起作用

时间:2019-05-02 07:56:23

标签: mongodb mongoose hapijs

我目前在hapi.js api调用中具有以下猫鼬功能

    server.route({
    method: "PUT",
    path:"/api/blockinfo/{hash}",
    handler: async (request, h) => {
        try{
            var jsonPayload = JSON.parse(request.payload)
            console.log(jsonPayload)
            var result = await BlockModel.findOneAndUpdate(request.params.hash, {$set: { height : jsonPayload[Object.keys(jsonPayload)[0]]}},  {new: true});
            return h.response(result);
        }catch{

            return h.response(error).code(500);
        }
    }
})

其目标基本上是使用PUT更新值。在上述情况下,它将更新场高,并且可以正常工作。

但是,如果我想更新任意字段怎么办?

例如,我的对象格式如下:

{"_id":"5cca9f15b1b535292eb4e468", "hash":"d6e0fdb404cb9779a34894b4809f492f1390216ef9d2dc0f2ec91f95cbfa89c9", "height":301651, "size":883, "time":1556782336, "__v":0}

在上述情况下,我使用$set更新了高度值,但是如果我决定输入2个随机字段来进行更新,例如大小和时间,该怎么办?

这是我的邮递员地址:

{
    "size": 300,
    "time": 2
}

很明显,它在上面的代码中不起作用,因为集合中缺少这些字段。

那么我如何使该设置自动识别需要更新的内容?

我试图用以下代码简化它,但它不会更新任何内容

    server.route({
    method: "PUT",
    path:"/api/blockinfo/{hash}",
    handler: async (request, h) => {
        try{
            var result = await BlockModel.findOneAndUpdate(request.params.hash, request.payload,  {new: true});
            return h.response(result);
        }catch{

            return h.response(error).code(500);
        }
    }
})

模式

const BlockModel = Mongoose.model("blocks", {
  hash: String,
  height: Number,
  size: Number,
  time: Number
});

3 个答案:

答案 0 :(得分:1)

问题出在您的hash键上。 findOneAndUpdate函数中的第一个参数/参数应为key value对。在这里,您直接放置key

应该是

handler: async (request, h) => {
  try {
    const { hash } = request.params
    var result = await BlockModel.findOneAndUpdate({ hash }, request.payload,  { new: true })
    return h.response(result)
  } catch (err) {
    return h.response(error).code(500)
  }
}

更新:

您以错误的方式定义了猫鼬模型。模式不只是一个对象。它应该是猫鼬对象。像这样

const schema = new Mongoose.Schema({
  hash: String,
  height: Number,
  size: Number,
  time: Number
})

export default Mongoose.model("blocks", schema)

答案 1 :(得分:0)

您尚未在简化代码中添加$set,并补充说它应该可以工作。 将payload作为带有必填字段的对象发送。

server.route({
    method: "PUT",
    path:"/api/blockinfo/{hash}",
    handler: async (request, h) => {
        try{
            var result = await BlockModel.findOneAndUpdate(request.params.hash, { $set: request.payload } ,  {new: true});
            return h.response(result);
        }catch{

            return h.response(error).code(500);
        }
    }
})

答案 2 :(得分:0)

handler: async (request, h) => {
        try{
            var result = await BlockModel.findOneAndUpdate(request.params.hash, JSON.parse(request.payload ),  {new: true});
            return h.response(result);
        }catch{

            return h.response(error).code(500);
        }
    }

由于我们正在更新JSON,因此有效负载必须为JSON格式