如果我不指定要更新的字段,猫鼬 findOneAndUpdate 将无法正常工作

Mongoose findOneAndUpdate not working if I dont specify the field to update

我目前在 hapi.js api 调用中有以下 mongoose 函数

    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
});

您的 hash 密钥有问题。 findOneAndUpdate 函数中的第一个 parameter/argument 应该是 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)

您没有在您的简化代码中添加 $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);
        }
    }
})
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 格式