mongodb - 为什么 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);
});
};
这将在控制台中返回以下内容:
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 值,但不能更新小部件,即使小部件的值只是一个字符串或数字......
解决方案
我发现了这个问题。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)
}
})
推荐阅读
- windows - 尝试搜索 Windows 更新时出错
- excel - 使用 VBA 代码提取单词表以分隔 excel 工作表
- javascript - 更新 sessionStorage 中对象的值
- c# - 必须使用 OUTPUT INTO 声明标量变量“@ID”
- python-3.x - 从 Google colab notebook 运行 java 命令
- python-3.x - 如何在对象检测 API 中使用 GCP 视觉训练模型
- html - SCSS 背景颜色未显示(angular2+ typescript)
- python - Python正则表达式在文本字符串中查找算术表达式
- java - java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 在构建正常的 struts 登录应用程序
- charts - 如何创建在 Tableau 中对齐的气泡图?