期望的行为
当对象的位置之一改变时,我正在尝试更新对象数组中每个对象的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 (statement
5 has been moved to position
0 )
我尝试过的事情
伪代码
我认为逻辑可以表示为:
对象位置将从old_position更改为 new_position任意数量的位置。
如果reposition_direction向后,则所有具有位置的对象 大于或等于new_position应该增加(除 被移动的对象,应为其指定new_position)
如果reposition_direction向前,则所有具有位置的对象 小于或等于new_position的值应减小(除 要移动的对象,应为其分配new_position)
( update :此逻辑不正确,已添加工作逻辑以回答)
这是我到目前为止所拥有的:
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" });
}
});
答案 0 :(得分:0)
每次更改数组时,都要在其每个成员上设置位置:
for (var i = 0; i < statements.length; i++) {
statements[i].position = i;
}
答案 1 :(得分:0)
有人建议更好的主意是获取数组,遍历结果,然后设置整个数组的值,但是我很想知道是否可以正确地执行排序逻辑,我认为以下作品。只需粘贴下面以供参考。
var new_position = Number(request_body.new_position);
var old_position = Number(request_body.old_position);
var reposition_direction = request_body.reposition_direction;
var statement_id = request_body.statement_id;
var filter = { _id: o_id };
if (reposition_direction === "backwards") {
// if backwards, position filter is $gte new_position AND $lt old_position
var new_filter = { _id: o_id, "statements.position": { $gte: new_position, $lt: old_position } };
// increment
var new_update = { $inc: { "statements.$[elem].position": 1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $gte: new_position, $lt: old_position } }], "multi": true };
} else if (reposition_direction === "forwards") {
// if forwards, position filter is $lte new_position AND $gt old_position
var new_filter = { _id: o_id, "statements.position": { $lte: new_position, $gt: old_position } };
// decrement
var new_update = { $inc: { "statements.$[elem].position": -1 } };
var array_filters = { "arrayFilters": [{ "elem.position": { $lte: new_position, $gt: old_position } }], "multi": true };
}
collection.updateOne(new_filter, new_update, array_filters, function(err, doc) {
if (err) {
res.send(err);
} else {
// set the moved objects property to the new value
var new_filter = { _id: o_id, "statements.id": statement_id };
var new_update = { $set: { "statements.$.position": new_position } };
collection.findOneAndUpdate(new_filter, new_update, function(err, doc) {
if (err) {
res.send(err);
} else {
res.json({ response: "hurrah" });
}
});
}
});
成功处理程序对findOneAndUpdate()
的调用受到以下答案的启发:
https://stackoverflow.com/a/30387038
我测试了以下组合,它们似乎有效:
将1
移至4
将4
移至1
将0
移至5
将5
移至0
将1
移至2
将2
移至1
将0
移至1
将1
移至0
将4
移至5
将5
移至4