【问题标题】:Combining multikey index with single field index in Mongodb C# yields unexpected results在 Mongodb C# 中将多键索引与单字段索引相结合会产生意想不到的结果
【发布时间】:2021-06-13 12:01:06
【问题描述】:

鉴于我在 MongoDB 中有以下数据结构:

public class Chat 
{
    public ObjectId Id { get; init; }
    public string ExternalId { get; init; }
    public ICollection<string> ParticipantIds { get; init; }
}

并且在数据库中有 2 个文档如下:

{
   "_id" : ObjectId("604fd41cb86313a7d8c0dc91"),
   "ExternalId" : "1",
   "ParticipantIds" : [ 
       "a", 
       "b"
   ]
},
{
   "_id" : ObjectId("604fd41cb86313a7d8c0dc92"),
   "ExternalId" : "1",
   "ParticipantIds" : [ 
       "a", 
       "c"
   ]
}

...然后应用以下索引

var participantIdsAndExternalIdCompoundIndex = new CreateIndexModel<ChatData>(Builders<ChatData>.IndexKeys.Combine(
            Builders<ChatData>.IndexKeys.Ascending(chat => chat.ExternalId),
            Builders<ChatData>.IndexKeys.Ascending(chat => chat.ParticipantIds)
            ), new CreateIndexOptions { Unique = true });
        
        Collection.Indexes.CreateMany(new[] { participantIdsAndExternalIdCompoundIndex });

// The shell version
db.getCollection('chats').createIndex({ExternalId: 1, ParticipantIds: 1}, {unique: true})

我希望索引的创建没有任何问题,因为 ExternalId 和 ParticipantIds 的组合是唯一的。但是,我得到以下异常告诉我,在另一个文档中存在的 ParticipantIds 数组的任何一个值与现有的 ExternalId 相结合都违反了唯一性。 我还在 shell 中运行了相同的结果,结果相同:

E11000 duplicate key error collection: messageServiceDb.chats index: ExternalId_1_ParticipantIds_1 dup key: { : "1", : "a" }

所以我的问题是;这是预期的行为吗?如果是这样,是否有另一种方法在 MongoDB 中使用索引来完成相同的行为?

【问题讨论】:

  • @Llama 没有。
  • /* 1 */ [ { "v" : 2, "key" : { "id" : 1 }, "name" : "_id", "ns " : "messageServiceDb.chats" } ] @Llama
  • 不,不是。在我的问题中,我说由于错误而无法创建索引。 @骆驼
  • 这正是我在我的问题中已经写的。
  • docs 状态“为了索引包含数组值的字段,MongoDB 为数组中的每个元素创建一个索引键。,所以我希望为第一个对象创建索引键 1/A 和 1/B,为第二个对象创建 1/A 和 1/C。虽然在单个文档中可能有重复的索引键,但在具有唯一约束的文档之间不可能出现重复的索引键。因此,这是预期的行为。也许将 id/参与者 id 与唯一索引结合起来的附加字段会有所帮助。

标签: c# .net mongodb nosql


【解决方案1】:

当你索引一个数组字段时,你可以认为数组中的值被分解成单独的文档,然后这些文档被独立索引(这些值被单独添加到索引中,但所有索引条目都指向原始文件)。

因此,在您的示例中,索引数据将是

(1, a) -> ...91*
(1, b) -> ...91

(1, a) -> ...92 *
(1, c) -> ...92

标有星号的两个条目冲突。

【讨论】:

    猜你喜欢
    • 2013-05-28
    • 1970-01-01
    • 2012-11-16
    • 2019-04-05
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    相关资源
    最近更新 更多