javascript - MongoDB 获取 ArrayFilters 引用以更新值
问题描述
我最近开始使用 MongoDB,我正在尝试更新文档中的一些属性,但无法获取对象引用来更新值。
请考虑以下数据:
const data = {
weekplanId: 'someid',
days: [
{label: 'Monday', cost: 20, comment: "some comment" },
{label: 'Tuesday', cost: 40, comment: "..." }
]
}
const update = await weekplan.updateOne(
{
_id: new ObjectId(data.weekplanId),
},
{
$set: {
"weekdays.$[i].cost": data.days.$[i].cost,
"weekdays.$[i].comment": data.days.$[i].comment,
"weekdays.$[i].date": new Date(),
"weekdays.$[i].someproperty": "something",
}
},
{
arrayFilters: [
{
"i.label": {
$in: data.days.map(p => p.label),
},
}]
}
);
如何引用数组对象来设置属性值?我知道data.days.$[i].cost
并且data.days.$[i].comment
错了,它们只是我努力实现的一个例子。
设置date
和someproperty
按预期工作,因为这些值不依赖于源数据。
我想尝试在不使用 JS 的情况下做到这一点。
arrayFilters 甚至适合这个吗?我会很感激一些关于在哪里看的指导。
提前致谢!
###编辑:
预期输出:
"_id": {"someid"},
"weekdays": [
{
"day": "Monday",
"cost": 20,
"comment": "some comment",
"date": 2021-08-01T19:51:45.057Z
"someproperty": "something"
},
{
"day": "Tuesday",
"cost": 40,
"comment": "...",
"date": 2021-08-01T19:51:45.057Z
"someproperty": "something"
},
...
...
...
]
工作日的其余时间(周三、周四、周五)将在此更新中保持不变。
解决方案
在该示例代码data.days.$[i].cost
中,在提交查询之前在客户端评估代码,因此$set
当服务器接收到它时,将分配给对象的相应字段的任何值(或缺少值)。
该data
对象不会随查询一起发送到服务器,因此即使它能够对输入值进行数组查找,输入值也不存在。
实现这一点的方法是在客户端迭代数组,并以编程方式构建更新查询。也许是这样的:
let labelChar = 105;
let setOps = {};
let filters = {};
data.days.forEach( function(day) {
let char = String.fromCharCode(labelChar++);
setOps['weekdays.$[' + char + '].cost'] = day.cost;
setOps['weekdays.$[' + char + '].comment'] = day.comment;
setOps['weekdays.$[' + char + '].date'] = new Date();
setOps['weekdays.$[' + char + '].someproperty'] = "something";
let filterObj = {};
filterObj[char + '.label'] = day.label;
filters.push(filterObj);
});
const update = await weekplan.updateOne(
{
_id: new ObjectId(data.weekplanId),
},
{
$set: setOps
},
{
arrayFilters: filters
}
);
对于提供的示例输入,这将提供更新:
.updateOne(
{
_id: new ObjectId(data.weekplanId),
},
{
$set: {
'weekdays.$[i].cost': 20,
'weekdays.$[i].comment': 'some comment',
'weekdays.$[i].date': ISODate(),
'weekdays.$[i].someproperty': 'something',
'weekdays.$[j].cost': 40,
'weekdays.$[j].comment': '...',
'weekdays.$[j].date': ISODate(),
'weekdays.$[j].someproperty': 'something'
}
},
{
arrayFilters: [
{'i.label': 'Monday'},
{'j.label': 'Tuesday'}
]
}
);
推荐阅读
- sql - Postgres 获得具有不同值的下一行
- django - Django - 更新缺少日期值的字典,设置为 0
- html - 提交 HTML 表单 - 防止重定向和捕获 JSON 响应
- php - 使用 base64Encode 将图像上传到服务器失败
- angular - Syncfusion Angular PDF Viewer Control - Passing Headers Along
- rest - 如何使用 Spark 框架公开指标?
- docker - go: 在声明性 Jenkinsfile 中找不到
- java - 多个读/写服务器客户端
- google-app-engine - 部署多个 enpoint api 谷歌应用引擎
- java - 无法从 Spring 应用程序启动多个 HTTPS 连接