4

我正在尝试使用 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
}
4

4 回答 4

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 } )
于 2012-11-16T17:25:06.233 回答
0

是的,mongo 允许更新多个文档。只需使用修饰符操作multi=True. 例如,order对于所有order大于 5 的文档,这会增加 1:

todos.update({'order':{'$gt':5}}, {'$inc':{'order':1}}, multi=True)

至于最好的方法,通常最好使用“自然”排序(按名称、日期、优先级等),而不是为此创建一个假字段。

于 2012-11-16T16:55:42.343 回答
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}});
}
于 2013-04-03T01:59:03.293 回答
0

如果您在猫鼬中使用本机承诺(es6),mongoose.Promise = global.Promise您可以执行以下批处理:

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)
}
于 2016-05-19T21:19:49.100 回答