mongodb - 为什么 mongodb upsert 计数器不反映实际变化?
问题描述
考虑以下查询
var collectionName = "test";
db.createCollection(collectionName);
db.getCollection(collectionName).insert({
"_id" : 1, "char" : "Gandalf", "class" : "barbarian", "lvl" : 20
});
db.getCollection(collectionName).bulkWrite([
{
insertOne: {
"document": {
"_id" : 2, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
}
}
},
{
updateOne: {
filter: { "_id": 1},
update: { $set: {"class" : "mage"} },
upsert: true
}
}
])
结果是:
{
"acknowledged" : true,
"deletedCount" : 0.0,
"insertedCount" : 1.0,
"matchedCount" : 1.0,
"upsertedCount" : 0.0,
"insertedIds" : {
"0" : 2.0
},
"upsertedIds" : {}
}
我的问题是为什么不更新id:1
文档upsertedIds
?这个文档不是刚刚用 upsert 更新了吗?还是我错过了什么?
根据文档,upsert
如果它没有找到任何文档,它只会添加信息(所以它实际上更像inserted
),但这种情况下我不知道哪些项目得到了更新。
执行查询时是否可以获取修改了哪些文档?
为避免 XY 问题:我希望查看失败的批量操作项(例如,当尝试使用 更新不存在的文档时upsert:false
)以及触发失败的日志 ID。
解决方案
您可以在准备批量更新时收集文档 ID,然后检查更新后哪些不存在。例如,对于您更新的文档 ID 1、2 和 3upsert:false
db.test.aggregate([
{ $group: { _id: null }},
{ $project: { _id: [ 1, 2, 3 ] }},
{ $unwind: "$_id" },
{ $lookup: {
from: "test",
localField: "_id",
foreignField: "_id",
as: "exists"
}},
{ $match: { exists: { $size:0 }}},
{ $project: { exists:0 }}
])
将返回与任何文档都不匹配的过滤器的 id,即您的术语中的“失败”。
推荐阅读
- c - 计算和打印矩阵的对角线之和
- javascript - 如何在 Angular 中使用 addEventListener 和 postMessage?
- php - 如何将日期、时间和值从单选按钮放入数据库
- c# - 逐个像素地动态绘制和显示,有一些延迟
- npm - 如何从 Nexus oss 代理获取依赖于 github 项目的 npm 包
- django - Django 测试 - 发送包含整数的数组数组
- android - 在 android 中使用改造登录
- json - 我如何在 nunjuncks 中乘以数据?
- swift - 为什么不能在swift中将可变参数标记为inout?
- vue.js - Vue Js 2 / Vue-CLI 3 / 托管时显示空白页