mongodb MongDB批量写入UpdateOne w/upsert选项插入新文档(c#驱动程序)

pbgvytdp  于 2023-02-07  发布在  Go
关注(0)|答案(1)|浏览(170)

我有一个需要经常更新的集合。结构如下:

{
  ObjectId _Id;
  string EntryKey;
  string Description;
  string SearchTerm;
}

EntryKey字段上有一个唯一的索引,我创建如下upsert操作:

var filter = filterBuilder.Eq(e => e.EntryKey, model.EntryKey);
var update = updateBuilder.Combine(
  updateBuilder.SetOnInsert(e => e._Id, ObjectId.GenerateNewId()),
  updateBuilder.SetOnInsert(e => e.EntryKey, model.EntryKey.ToLower()),
  updateBuilder.Set(e => e.Description, model.Description),
  updateBuilder.Set(e => e.SearchTerm, model.SearchTerm));

var op = new UpdateOneModel<SearchEntry>(filter, update){ IsUpsert = true, Hint = "EntryKey_1" };
bulkList.Add(op);

在每个测试中使用完全相同的输入数据和新的mongo示例,第一次迭代成功,第二次迭代失败,EntryKey字段为E10000: duplicate key error collection
当我从索引中删除唯一约束时,集合中会创建重复的文档(_Id除外)
当我使用相同的失败ID在shell中运行命令时,命令成功并且文档被更新。

db.search.bulkWrite([
  {
    updateOne: {
      "filter": { "EntryKey": "ad544f72-496f-4eee-bf53-ffdda57de824" },
      "update": {
        $setOnInsert: {
          _id: ObjectId(),
          "EntryKey": "ad544f72-496f-4eee-bf53-ffdda57de824"
        },
        $set: {
          "Description": "This is a description",
          "SearchTerm",: "search"
        }
      },
      "upsert": true
    }
  }
]);

我希望与过滤器 predicate 匹配的文档得到更新,而不是抛出重复键错误(当强制使用唯一索引时)或插入本质上重复的文档。
我在this问题中看到,可接受的答案是将更新与插入分开。如果是这样的话,那么如果不能以这里尝试的方式使用upsert,那么它的意义何在?

xqk2d5yq

xqk2d5yq1#

当代码第一次运行时,它将创建一个文档,其中EntryKey设置为model.EntryKey.ToLower()
在第二次运行中,将EntryKeymodel.EntryKey进行比较,因为在upsert中它是小写的,所以只有在model.EntryKey中没有大写字母时才匹配。
如果有,过滤器将无法匹配,并将尝试upsert,但在转换为小写后失败。
为了保持一致性,还要在筛选器中使用小写,如

var filter = filterBuilder.Eq(e => e.EntryKey, model.EntryKey.ToLower());

相关问题