E11000 重复键错误索引:创建唯一索引时

Juh*_*han 5 javascript indexing mongodb robo3t

我正在 robomongo 中运行下面的查询。机器人它给出如下所示的错误?我真的想使用此查询删除 url 字段中的重复条目。我的查询有问题吗?

db.dummy_data.createIndex({"url":1},{unique:true},{dropDups:true})
Run Code Online (Sandbox Code Playgroud)

我的错误是 E11000 重复键错误索引:mydb.dummy_data.$url_1 dup key: {"some url"}

Nei*_*unn 3

因此,当您的语法从不正确的用法更正为:

db.dummy_data.ensureIndex({ "url": 1},{ "unique": true, "dropDups": true })
Run Code Online (Sandbox Code Playgroud)

您报告说您仍然收到一条错误消息,但是一条新消息:

{ "connectionId" : 336, "err" : "在使用 dropDups=true 构建索引时也可能出现重复", "code" : 10092, "n" : 0, "ok" : 1 }

谷歌群组上有一条消息,它导致了建议的方法:

嗨丹尼尔,

该断言表明重复项的数量达到或超过 1000000。此外,源代码中有一条评论说:“我们可以将这些在磁盘上排队,但通常重复项很少,因此我们保留在 ram 中并有一个限制。” (其中限制 == 1000000),因此最好从一个空集合开始,使用 {dropDups: true} 确保索引,然后重新导入实际文档。

让我们知道这是否更适合您。

因此,正如建议的那样,创建一个新集合并导入其中的所有内容。基本前提:

db.newdata.ensureIndex({ "url": 1},{ "unique": true, "dropDups": true });

db.dummy_data.find().forEach(function(doc) {
    db.newdata.insert(doc);
});
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

db.newdata.ensureIndex({ "url": 1},{ "unique": true, "dropDups": true });

var bulk = db.newdata.initializeUnOrderedBulkOp();
var counter = 0;

db.dummy_data.find().forEach(function(doc) {
    counter++;
    bulk.insert( doc );

    if ( counter % 1000 == 0 ) {
        bulk.execute();
        bulk = db.newdata.initializeUnOrderedBulkOp();
    }
});

if ( counter % 1000 != 0 )
    bulk.execute();
Run Code Online (Sandbox Code Playgroud)

然而,您如何从一个集合迁移到另一个集合,在唯一键上存在大量重复项,这似乎是目前处理它的唯一方法。

  • 仅供参考, [`dropDups`](http://docs.mongodb.org/manual/core/index-creation/#index-creation-duplicate-dropping) 选项仅适用于使用现有数据在集合上构建唯一索引时。如果您复制到新集合中,则会引发正常的重复键异常(您可以选择忽略)。还值得注意的是,根据 [SERVER-14710](https://jira.mongodb.org/browse/SERVER-14710),在 2.7.x 开发周期中删除了“dropDups”支持。非确定性数据删除可能会导致一些意想不到的后果(特别是打字错误或使用错误)。 (2认同)