首页 > 解决方案 > 为什么 express/mongodb updateOne post 允许 $set 某些值,但不会更新其他值?

问题描述

我对这个 post 方法感到困惑,它会更新字段“x 和 y”,但是任何设置小部件数组的尝试都会失败。它正在寻找要更新的正确项目,传递所有必需的信息,但它不允许插入或更新到“小部件”字段。

即使我删除了用于小部件的数据并通过“foo”任意发送,它也不会使用“小部件”字段进行更新。

我在这里做错了什么???

更新小部件的 API 调用。任意 X 和 Y 值将在数据库中更新,但任何更新小部件的尝试都不会改变

const saveUpdatedWidgets = async (update, _id) => {
    console.log("called to update widgets ",update.widgets," in pagecard saveUpdatedWidgets")
    let widgetObject = []
    for(let u=0;u<update.widgets.length;u++){
        widgetObject.push({
            id: update.widgets[u].id,
            text: update.widgets[u].text
        })
    }
    Api.withToken().post('/pagewidget/'+_id,
        {widgets: widgetObject, x:250, y:250}
    ).then(function (response) {
        console.log("?worked ",response.data)
    }).catch(function (error) {
      console.log("page save failed for some reason on pagecard: ",error.response);
    });
};

这将在控制台中返回以下内容:

saveUpdatedWidgets 方法的控制台

post方法的代码是:

//THIS ROUTER WILL NOT UPDATE ANY WIDGETS FOR SOME REASON
router.post('/pagewidget/:_id',auth, async(req,res)=>{
    console.log("request to update ",req.body," for id ",req.params," in pagewidgetsave post")
    const query = { "_id": req.params };
    const addedWidgets = req.body;
    const newValues = { $set: addedWidgets }
    try {
        const thePage = await Pages.updateOne( query, newValues);
        res.status(201).send(thePage)
        console.log("updated Page: ",thePage);
    }
    catch(e){
        console.log(e);
        res.status(400).send(e)
    }
})

控制台运行节点的结果显示值正在通过,但数据库中只有 x 和 y 实际更新。

节点控制台

控制台对呼叫的响应

如果这里有任何问题,这里是 axios api.js 文件:

import axios from 'axios';

const baseURL = process.env.REACT_APP_BASE_URL || "http://localhost:3001"

export default {
  
  noToken() {
    return axios.create({
      baseURL: baseURL
    });
  },
  
  withToken() {
    const tokenStr = window.sessionStorage.getItem("token")
    return axios.create({
      baseURL: baseURL,
      headers: {"Authorization" : `Bearer ${tokenStr}`}
    });
  } 
}

到底是怎么回事!!??它发现页面正常,并更新 x 和 y 值,但不能更新小部件,即使小部件的值只是一个字符串或数字......

标签: mongodbexpressmongooseaxios

解决方案


我发现了这个问题。MongoDB 文档并没有很好地提及这一点,在其 updateOne() 示例中,它为 update 参数传递了一个对象。但是,如果您要设置一个新字段,则必须将此参数包装在数组中才能使用 $set,这是因为它可以接受 $set 和 $unset 两种方法。(参见 mongoDB 文档)(即 updateOne({query} , [{$set: {field:"value"}, {$unset: {otherfield:"othervalue"}])

最后 post 方法只需要更改为 const thePage = await Pages.updateOne(query, [newValues]); (将 newValues 作为对象存储在数组中,以便在需要时添加 $unset 。

这就是为什么它可以更新现有值,但不会将新值设置到数据库中。

多么美妙的旅程……

post方法的完整代码在这里

router.post('/pagewidget/:_id',auth, async(req,res)=>{
    const query = {"_id": req.params._id};
    const addedWidgets = req.body;
    const newValues = { $set: addedWidgets }
    try {
        const thePage = await Pages.updateOne( query, [newValues]);
        res.status(201).send(thePage)
        console.log("updated Page: ",thePage);
    }
    catch(e){
        console.log(e);
        res.status(400).send(e)
    }
})

推荐阅读