【发布时间】:2018-09-11 11:34:39
【问题描述】:
期望的行为
当其中一个位置发生变化时,我正在尝试更新对象数组中每个对象的 position 属性。例如,位置为5 的对象移动到位置0,因此其他对象的位置也必须改变。
我无法为 MongoDB 找到“数组迭代器”,因此一直在尝试从其他角度解决问题,但我认为我过于复杂了。
架构
statements: [
{
"position": 0,
"id": "a"
},
{
"position": 1,
"id": "t"
},
{
"position": 2,
"id": "z"
},
{
"position": 3,
"id": "q"
},
{
"position": 4,
"id": "l"
},
{
"position": 5,
"id": "b"
}
]
前端场景
Figure A: Starting state of ordered divs
Figure B: Changed state of ordered divs (statement5has been moved to position0)
我的尝试
伪代码
我认为逻辑可以表示为:
对象位置将从 old_position 更改为 new_position 任意数量的位置。
如果 reposition_direction 是向后的,所有有位置的对象 大于或等于 new_position 应该增加(除了 被移动的对象应该被分配 new_position)
如果reposition_direction是forward,所有有位置的物体 小于或等于 new_position 应该递减(除了 被移动的对象应该被分配 new_position)
(更新:此逻辑不正确,已添加工作逻辑以回答)
这是我目前所拥有的:
if (reposition_direction === "backwards") {
var new_filter = { _id: o_id, "statements.position": { $gte: new_position } };
var new_update = { $inc: { "statements.$[elem].position": 1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $gte: new_position } }], "multi": true };
} else if (reposition_direction === "forwards") {
var new_filter = { _id: o_id, "statements.position": { $lte: new_position } };
var new_update = { $inc: { "statements.$[elem].position": -1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $lte: new_position } }], "multi": true };
}
collection.updateOne(new_filter, new_update, array_filters, function(err, doc) {
if (err) {
res.send(err);
} else {
res.json({ response: "hurrah" });
}
});
【问题讨论】:
-
为什么要保留位置作为对象本身的单独“位置”属性。它们的位置是已知的,因为它们在一个数组中。任何时候你都需要遍历数组的位置,这样你就可以从数组的索引中知道它。
-
一年后,我意识到更简单的解决方案是
$pull来自数组的对象,然后$push使用$each和$position将其设置为所需的索引:stackoverflow.com/a/36084944
标签: javascript node.js mongodb