为什么mongodb upsert计数器不反映实际变化?

时间:2019-08-20 08:45:42

标签: mongodb

考虑以下查询

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。

1 个答案:

答案 0 :(得分:0)

您可以在准备批量更新时收集文档ID,然后检查更新后不存在的文档ID。例如。使用upsert:false

更新的文档ID 1、2和3
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,即您的术语中的“失败”。