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

Posted

技术标签:

【中文标题】有啥方法可以使用 mongoose 从 mongodb 批量操作中获取修改后的 IDS?【英文标题】:Any way to get the modified IDS from mongodb's bulk operations using mongoose?有什么方法可以使用 mongoose 从 mongodb 批量操作中获取修改后的 IDS? 【发布时间】:2016-03-12 19:14:49 【问题描述】:
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
    )

有什么方法可以实现吗?

【问题讨论】:

您是否可以选择从响应中获取修改后的 ID? 【参考方案1】:

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

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

在“批量”上下文中,大部分情况都适用,因为是否存在条件匹配,在这种情况下,您将分别获得 nMatchednModified 的返回值,因为还有如果要修改的数据已经是修改目标的值,则“匹配”文档实际上没有更新的可能性。

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

但是,在区分“upsert”操作和实际“updates”的情况下,您可以设置一个 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”列表进行匹配以查看“什么不存在”,基本上会返回可能刚刚修改的内容。当然需要注意的是,如果值已经与修改相同,那么它根本就不是修改。

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

【讨论】:

感谢您的扩展回答。我想没有办法知道(无论如何都是批量)哪些文档实际上被修改了,只是有些人做了。 @Martol1ni 这是nModified 的一般警告(实际上只有在较新的批量操作 API 下才会正确报告,因为旧版 API 报告即使值相同也已修改)除非您是一次查看一个更新(和一个文档),与nMatched 相比,它实际上并不能表明有多少文档受到影响。因此,如果有什么数字会“超过”报告,而不是“低于” @BlakesSeven 我看到你的例子是特定于 upsert 的。你能想出一个替代方法来返回批量 find().update() 的 ID 吗?

以上是关于有啥方法可以使用 mongoose 从 mongodb 批量操作中获取修改后的 IDS?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 mongoose 的 mongo 文档中返回一个数组?

在 updateOne mongoose 方法中更新现有或使用 mongo 运算符的功能

如何从服务器端 express/mongo/mongoose 中的 URL,客户端的 axios/react/redux 中获取参数 ID

(Mongo/Mongoose) 如何处理等待多个查询的结果

有啥方法可以克服mongo数据库中createview查询中的内存超出错误

Mongo/Mongoose 中的复杂约束