2011-12-30 106 views
3

我有一个嵌套有序项目数组的文档,我需要自动重新排列数组中的项目。原子序列MongoDB文档嵌套数组中的项目

  1. 服务器端代码是否适合此任务?
  2. 服务器端代码是这个任务的唯一解决方案吗?
  3. 在巫范围这个代码将阻塞:
    • 单个文档
    • 单个集合
    • 整个服务器?

这是将在服务器侧执行的代码:

var reorder = function (
    catalog_id, 
    parent_id, 
    item_id, 
    new_pos) { 

    var old_pos; 

    var collection = db.catalogs; 
    var catalog = collection.findOne({catalog_id:catalog_id}); 
    var result = []; 

    for(i in catalog.list) { 

     var item = catalog.list[i]; 

     if(item.id == item_id) { 

      old_pos = item.order; 
      result.push({old_pos:old_pos}); 
      break; 
     } 
    } 

    if(old_pos == new_pos) 
     return result; 

    var up = new_pos < old_pos; 

    catalog.list.forEach(function(item){ 

     if(item.parent == parent_id && 
      (up ? 
       (item.order <= old_pos && item.order >= new_pos) : 
       (item.order <= old_pos && item.order >= new_pos))){ 

      if(item.id != item_id) { 

       item.order++; 
       result.push({down:item}); 
      } 
      else { 

       item.order = new_pos; 
       result.push({up:item}); 
      } 

      collection.update(
       {catalog_id:catalog_id, 'list.id':item.id}, 
       {$set:{'list.$.order':item.order}}); 
     } 
    }); 

    return result; 
}; 

reorder('diagnostic_graph', 'n1', 'n5', 1); 

这是一个样本数据:

{ 
    "_id" : ObjectId("4efc939094f4a115d80c8543"), 
    "catalog_id" : "diagnostic_graph", 
    "list" : [{ 
     "id" : "n1", 
     "order" : 0 
    }, { 
     "id" : "n2", 
     "parent" : "n1", 
     "order" : 0 
    }, { 
     "id" : "n3", 
     "parent" : "n1", 
     "order" : 1 
    }, { 
     "id" : "n4", 
     "parent" : "n1", 
     "order" : 2 
    }, { 
     "id" : "n5", 
     "parent" : "n1", 
     "order" : 3 
    }] 
} 

PS。对不起,如果有什么不清楚 - 英语不是我最好的技能

+0

我不确定这个操作是否会自动运行。据我所知,它会产生锁定。 – 2011-12-30 13:32:38

+2

但是,您可以在客户端计算所有这些信息,然后原子重写文档。 – 2011-12-30 13:37:48

+1

我想MongoDB家伙们建议使用[Update if Current Update](http://www.mongodb.org/display/DOCS/Atomic+Operations#AtomicOperations-%22UpdateifCurrent%22)方法(类似于CAS(“change-and-set “)在memcached中)的原子文档更改无法用”更新修饰符“表示。 – 2011-12-30 13:55:08

回答

0

问1.服务器端代码是否是这个任务的正确解决方案?

A 1.这取决于。如果数组需要在使用时重新排序,那么每当将数组添加到数组时,都应重新排序。无论何时将项目推送到数组,或者在应用程序中执行,都可以调用服务器端.js代码。

问2.服务器端代码是否是此任务的唯一解决方案?

答2.正如我在第一个问题的答案中所说的那样,它不是唯一的解决方案。

问题3在女巫范围这个代码将阻塞:

A 3.答案是单个文档(AFAIK)。