MongoDB似乎不尊重复合指数的唯一性约束

时间:2016-11-01 06:18:13

标签: mongodb unique-constraint compound-index

我有一个大约有5亿个文档的集合,似乎没有对这些文档的特定子集强制执行唯一性约束。唯一性约束适用于复合指数。

此集合的索引:

db.elements.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.elements"
        },
        {
                "v" : 1,
                "key" : {
                        "sessionId" : 1
                },
                "name" : "sessionId_1",
                "ns" : "test.elements"
        },
        {
                "v" : 1,
                "key" : {
                        "sessionId" : 1,
                        "modelFolder" : 1,
                        "modelName" : 1
                },
                "name" : "sessionId_1_modelFolder_1_modelName_1",
                "ns" : "test.elements",
                "options" : {
                        "unique" : true
                }
        },
        {
                "v" : 1,
                "key" : {
                        "id" : 1
                },
                "name" : "id_1",
                "ns" : "test.elements",
                "options" : {
                        "unique" : false
                }
        },
        {
                "v" : 1,
                "key" : {
                        "uniqueId" : 1
                },
                "name" : "uniqueId_1",
                "ns" : "test.elements"
        }
]

当我运行以下查询时,尽管在索引'sessionId_1_modelFolder_1_modelName_1'的复合索引字段上查询匹配(由于IP问题而编辑的特定字段值),但我得到重复:

var gs = (
    db
    .elements
    .aggregate(
        [
          {
            $match : {
              "sessionId" : (specific sessionId value),
              "modelName" : (specific modelName value),
              "modelFolder" : (specific modelFolder value)
            }
          },
          {
            $group : {
              _id : "$id",
              total : { $sum : 1 }
            }
          }
        ]  
      )
  );

gs.forEach(
    function(g) { printjson(g); }
  );

输出的一个子集:

{ "_id" : 1394912, "total" : 2 }
{ "_id" : 1394916, "total" : 2 }
{ "_id" : 1394914, "total" : 2 }
{ "_id" : 1394909, "total" : 2 }
{ "_id" : 1394877, "total" : 2 }
{ "_id" : 1394908, "total" : 2 }
{ "_id" : 1394900, "total" : 2 }
{ "_id" : 1394906, "total" : 2 }
{ "_id" : 1394907, "total" : 2 }
{ "_id" : 1394876, "total" : 2 }
{ "_id" : 1394904, "total" : 2 }
{ "_id" : 1394902, "total" : 2 }
{ "_id" : 1394903, "total" : 2 }
{ "_id" : 1394881, "total" : 2 }
{ "_id" : 1394859, "total" : 2 }
{ "_id" : 1394901, "total" : 2 }
{ "_id" : 1394878, "total" : 2 }
{ "_id" : 1394880, "total" : 2 }
{ "_id" : 1394857, "total" : 2 }
{ "_id" : 1394875, "total" : 2 }

我已经杀死了这个文档子集的批量插入,然后重新批量插入它们,但我很惊讶这种方式允许重复。我是疯了还是在某些情况下这可能?

1 个答案:

答案 0 :(得分:0)

_id对于mongodb中的集合是唯一的。

如果我们处于分片环境中,可能会出现重复ID。

为避免重复,请使用{unique:true}选项以确保基础索引强制唯一性,只要唯一索引是分片键的前缀即可。

如果未使用“unique:true”选项,则分片键不必是唯一的。

参考文献:

https://docs.mongodb.com/manual/sharding/

Duplicate documents on _id (in mongo)

阅读此post以获取有关不同馆藏中的重复_id的更多信息