我正在尝试使用Javascript,Python和MongoDB创建自己的待办事项列表。我对如何处理任务排序感到困惑。
我目前的想法是在每个任务文档中都有一个订单字段,当订单在客户端上发生变化时,我会从数据库中获取任务列表并单独/按顺序重新排序每个任务。这似乎很尴尬,因为大型待办事项列表意味着大量的查询。有没有办法按顺序更新多个文档中的字段?
我也在寻找关于这是否是最好的方法的建议。我希望能够保持待办事项列表顺序,但也许我会以错误的方式进行。
{
"_id" : ObjectId("50a658f2cace55034c68ce95"),
"order" : 1,
"title" : "task1",
"complete" : 0
}
{
"_id" : ObjectId("50a658fecace55034c68ce96"),
"order" : 2,
"title" : "task2",
"complete" : 1
}
{
"_id" : ObjectId("50a65907cace55034c68ce97"),
"order" : 3,
"title" : "task3",
"complete" : 1
}
{
"_id" : ObjectId("50a65911cace55034c68ce98"),
"order" : 4,
"title" : "task4",
"complete" : 0
}
{
"_id" : ObjectId("50a65919cace55034c68ce99"),
"order" : 5,
"title" : "task5",
"complete" : 0
}
答案 0 :(得分:2)
Mongo对查询的速度非常快,您不应该像使用全功能关系数据库一样关注性能。如果你想要谨慎,只需创建一个1k项目的待办事项列表并试用它,它应该是非常即时的。
for (var i = 0; i < orderedListOfIds.length; i++)
{
db.collection.update({ '_id': orderedListOfIds[i] }, { $set: { order:i } })
}
然后
db.collection.find( { } ).sort( { order: 1 } )
答案 1 :(得分:0)
是的,mongo允许更新多个文档。只需使用modifier operation和multi=True
即可。例如,对于order
大于5的所有文档,这会将order
递增1:
todos.update({'order':{'$gt':5}}, {'$inc':{'order':1}}, multi=True)
至于最好的方式,通常最好使用“自然”排序(按名称,日期,优先级等),而不是仅为此创建假字段。
答案 2 :(得分:0)
我正在做类似的事情。我在列表项中添加了一个字段ind
。以下是我将列表项移动到新位置的方法:
moveItem: function (sourceIndex, targetIndex) {
var id = Items.findOne({ind:sourceIndex})._id;
var movinUp = targetIndex > sourceIndex;
shift = movinUp ? -1 : 1;
lowerIndex = Math.min(sourceIndex, targetIndex);
lowerIndex += movinUp ? 1 : 0;
upperIndex = Math.max(sourceIndex, targetIndex);
upperIndex -= movinUp ? 0 : 1;
console.log("Shifting items from "+lowerIndex+" to "+upperIndex+" by "+shift+".");
Items.update({ind: {$gte: lowerIndex,$lte: upperIndex}}, {$inc: {ind:shift}},{multi:true});
Items.update(id, {$set: {ind:targetIndex}});
}
答案 3 :(得分:0)
如果您在mongoose mongoose.Promise = global.Promise
中使用本机承诺(es6),则可以执行以下操作进行批处理:
function batchUpdate(res, req, next){
let ids = req.body.ids
let items = []
for(let i = 0; i < ids.length; i++)
items.push(db.collection.findOneAndUpdate({ _id:ids[i] }, { $set: { order:i } }))
Promise.all(items)
.then(() => res.status(200).send())
.catch(next)
}