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

Mar*_*1ni 5 mongoose mongodb 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
    })
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这个目标?

Bla*_*ven 5

嗯,从一个角度来看,答案是“不”,这是有充分理由的。

一般来说,MongoDB 的“更新”操作旨在处理通常是“多个”文档的内容,因此意味着与条件匹配的任何内容。因此,这里的一般情况是您要求以单数形式更新或通过选择更新的内容是否已更新,具体取决于是否匹配任何内容。

在“批量”背景下,许多相同的道理也适用,因为有任何一个条件匹配与否,在这种情况下,你会得到的返回值nMatchednModifiedrepectively,因为还有一个“匹配”文件是可能性在当前要修改的数据已经是作为修改目标的值的情况下,实际上并未更新。

nMatched和之间的最后一个区别nModified“你不能可靠地做到这一点”的主要原因,因为并非所有匹配的东西都必须被修改。

但是,在区分“更新插入”操作和实际“更新”的情况下,您可以进行推测值。由于上述区别,它不会是 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
});
Run Code Online (Sandbox Code Playgroud)

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

[ { index: 0, _id: 1 } ]
Run Code Online (Sandbox Code Playgroud)

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

但是由于 API 的工作方式,这与您将要获得的一样接近。