【问题标题】:Updating multiple documents with different values更新具有不同值的多个文档
【发布时间】:2016-12-29 04:12:04
【问题描述】:

我正在使用 jquery ui 的可排序函数 (source) 重新排列元素。我已经构建了自定义回调来创建这些元素的列表。所以当我移动一个元素时,所有元素都会被赋予一个新的位置 id。它可能看起来像这样:

[{
    id_of_element_in_database: 12,
    new_position: 0
}, {
    id_of_element_in_database: 16,
    new_position: 1
}, {
    id_of_element_in_database: 14,
    new_position: 2
}]

我通过简单的 Ajax 发布

将此列表发送到我的后端
$.post('/position', { data: list });

路线

router.post('/position', (req, res) => {
    console.log(req.body.data); // This prints the array of objects above.
});

架构

mongoose.Schema({
    id: Number,
    position: Number,
    ...
});

现在我不知道如何有效地更改所有文档的位置。创建一个糟糕的数组循环并执行多个数据库请求并不是最好的方法。

我在这里试过了,感觉很不对。

for (let i in req.body.data) {
    collection.update({ id: req.body.data[i].id }, { position: req.body.data[i].position });

我必须做些别的事情来实现这一点。我试过谷歌没有任何运气。

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    您可以尝试使用 bulkWrite API 以更好的方式执行更新,而无需向服务器发出多次请求:

    var callback = function(err, r){
        console.log(r.matchedCount);
        console.log(r.modifiedCount);
    }
    // Initialise the bulk operations array
    var ops = req.body.data.map(function (item) { 
        return { 
            "updateOne": { 
                "filter": { 
                    "id": parseInt(item.id),
                    "position": { "$ne": parseInt(item.position) }
                },              
                "update": { "$set": { "position": parseInt(item.position) } } 
            }         
        }    
    });
    
    // Get the underlying collection via the native node.js driver collection object
    Model.collection.bulkWrite(ops, callback);
    

    【讨论】:

    • 谢谢!我会试试这个并回复你!
    • 通过这个小调整parseInt(item.id)parseInt(item.position) 并从集合中删除了unique 索引,这个解决方案完美地工作。谢谢!
    • @JonathanNielsen 不用担心,很乐意为您提供帮助。
    • @JonathanNielsen 从集合中删除 unique 索引听起来不仅仅是一个调整:您能告诉我们为什么这样做是必要的吗?
    • @VinceBowdren 我想“如果你想对它们进行排序,你当然不想拥有相同的位置编号”所以在我的模式中我做了{ type: Number, unique: true }。但是当我使用批量更新时,一些位置在其他位置之前发生了更改,因此两个文档可以在几秒钟内具有相同的位置编号。我去了 mongo shell 并做了db.collection.getIndexes() 来列出索引。我找到了我的唯一位置索引,并通过 db.collection.dropIndex('position_1') 将其删除。 position_1 是我的索引名称。在此之后,我还切换到了我上面写的架构设置。
    【解决方案2】:

    以下是我使用 Node.js 的方法:

    var forEach = require('async-foreach').forEach;
    var bulk = Things.collection.initializeOrderedBulkOp();
    
    
      Things.find({}).lean().execAsync(execSettings).then(function(resp){
    
        forEach(resp, function(template, index, arr) {
    
          var done = this.async();
    
          bulk.find({'_id': template._id}).update({$set: {_sid: generateShortId()}});
          bulk.execute(function (error) {
               done();                  
          });
    
        }, function(notAborted, arr){
    
            res.json({done: true, arr: arr.length});
    
        });
    
      });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 2013-06-16
      相关资源
      最近更新 更多