【问题标题】:Why does express/mongodb updateOne post allow $set of some values, but will not update others?为什么 express/mongodb updateOne post 允许 $set 某些值,但不会更新其他值?
【发布时间】:2021-12-11 10:15:16
【问题描述】:

我对这种 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);
    });
};

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

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 值,但无法更新小部件,即使小部件的值只是一个字符串或数字......

【问题讨论】:

  • 在致电 updateOne 之前尝试记录 querynewValues
  • 查询是 { _id: { _id: '617626a7179ca4113034d82e' } } newValues 是 { '$set': { widgets: [[Object] ], x: 250, y: 250 } }
  • $set 周围的引号是问题吗? $set 似乎确实有效,因为每当我在数据库中手动更改 x 和 y 时,它都会更新它们,然后拖动一个小部件来触发该功能..
  • 等等,我想我看到了,那里有一个双 _id 标签。 _id {_id
  • 可能说得太早了,删除双 ID 标签后,它仍在更新 x 和 y 值,但不会添加小部件(即使我传递 '2' 作为值而不是小部件对象)

标签: mongodb express mongoose axios


【解决方案1】:

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

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

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

多么美妙的旅程……

此处发布方法的完整代码

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

【讨论】:

  • "...此参数必须包装在数组中才能使用 $set..."。 update 方法主要接受两个参数 - filterupdate。更新可以是 regular 更新操作 或 使用聚合管道进行更新。这两种更新方式有不同的目的。您所说的“包装在数组中”是带有聚合管道的更新。
猜你喜欢
  • 2023-04-10
  • 2016-06-09
  • 2021-03-21
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 2013-05-08
  • 1970-01-01
相关资源
最近更新 更多