有什么方法可以使用mongoose从mongodb的批量操作中获取修改后的IDS?

时间:2015-12-08 00:59:12

标签: mongodb mongoose mongodb-query

let dbOperations = Edge.collection.initializeOrderedBulkOp()
edges.forEach(edge => {
    dbOperations.find({_id: edge.id}).upsert().updateOne({
        $set: {
            value: edge.value
        },
        $setOnInsert: {
            _id: edge.id
        }
    })
})
dbOperations.execute()
    .then(result => {
        console.log(result.nModified) // This shows the number of edges that is actually modified
        console.log(result.getModifiedIds()) // This is what I want to achieve
    })

有任何方法可以达到这个目的吗?

1 个答案:

答案 0 :(得分:2)

从一个观点来看,anwer是“不”,这是有充分理由的。

一般来说,MongoDB“更新”操作旨在跨越通常的“多个”文档,因此意味着符合条件的任何内容。所以这里的一般情况是你要么以单数形式要么更新,要么根据是否有任何匹配来更新或不更新。

在“批量”上下文中,大多数情况都适用,因为标准匹配与否,在这种情况下,您将分别获得nMatchednModified的返回值,因为还有可能实际更新“匹配”文档,其中要修改的数据已经是作为修改目标的值。

nMatchednModified之间的最后一个区别是“你无法可靠地执行此操作”的主要原因,因为并非必须修改所有匹配项。

但是,在识别“upsert”操作和实际“更新”之间,您可以创建 guestimate 值。由于所提到的区别,它不会100%精确,但基本过程是将输入列表与getUpsertedIds()的返回值进行比较,这是一个有效的调用。

目前避开世界其他地方的ES6语法:

var upserted = result.getUpsertedIds();    // get this from the bulk result

upserted = upserted.map(function(up) { return up._id }); // filter out just the _id values

var modifiedIds = edges.map(function(edge) {    // get _id only from source 
    return edge.id;  
}).filter(function(edge) {
    return upserted.indexOf(edge) == -1;        // and return only non upserted
});

来自.getUpsertedIds()的返回结果是一个对象数组,其中包含批量更新中的“索引”位置和“upsert”的生成或提供的_id值。

[ { index: 0, _id: 1 } ]

因此,将输入列表与“upserted”列表进行匹配,以查看“what not there”,基本上会返回可能刚刚修改过的内容。当然需要注意的是,如果值已经与修改相同,那么它根本就不是修改。

但是由于API的工作原理,它与您将获得的一样接近。