【问题标题】:Create index in MongoDB 3.2 to avoid duplicated documents/rows在 MongoDB 3.2 中创建索引以避免重复的文档/行
【发布时间】:2016-04-14 12:08:44
【问题描述】:

我正在使用 MongoDB 3.2,并希望避免在我的集合中出现重复项。为了做到这一点,我使用createIndex() 方法(我尝试了不同的变体,它们都不起作用):

dbColl.createIndex(new Document("guid", 1));
dbColl.createIndex(new BasicDBObject("guid", 1));
dbColl.createIndex(new Document("guid.content", 1));
dbColl.createIndex(new BasicDBObject("guid.content", 1));

然后我尝试执行数据插入:

itemsArr.forEach(
     item -> dbColl.insertOne(Document.parse(item.toString()))
);

我做了两次,预计第二次 MongoDB 不会添加任何新行,因为数据已经添加并且guid 字段上有索引。但是,尽管有索引值,MongoDB 却不会添加重复项。

我的问题是,为什么即使 guid 和/或 guid.content 字段上有索引,MongoDB 也会添加重复项?以及如何解决?我希望能够只添加一次具有相同guid 字段的文档。

以下是文档结构示例:

在我的数据中,guid 字段是唯一的文档标识符。

【问题讨论】:

  • 这不是真的。你为什么认为ChinaPost-f411f6... === skynews-1a2346...
  • @user3100115,实际上我的意思是如果我运行插入命令两次或更多次,那么 MongoDB 将添加两次或更多次ChinaPost-f411f6…。我不是将ChinaPost-f411f6…skynews-1a2346… 进行比较,而是将第一次执行的ChinaPost-f411f6… 与第二次执行插入的ChinaPost-f411f6… 进行比较,依此类推。

标签: java mongodb indexing duplicates crud


【解决方案1】:

常规索引允许多个文档具有相同的值。

您需要的不是常规索引,而是an unique index。这些是通过使用带有选项对象的createIndex(DBObject keys, DBObject options) 方法创建的,其中uniquetrue

collection.createIndex(new BasicDBObject("guid", 1), new BasicDBObject("unique", true));

【讨论】:

  • 谢谢菲利普,请您澄清一下,我是否正确理解此处描述的方法db.members.createIndex( { "user_id": 1 }, { unique: true } )docs.mongodb.org/manual/core/index-unique 已过时?
  • @MikeB。它没有过时这就是您创建唯一索引的方式。
  • @user3100115,那么db.members.createIndex( { "user_id": 1 }, { unique: true } )db.members.createIndex(new BasicDBObject("user_id", 1), new BasicDBObject("unique", true)); 有什么区别?完全一样吗?如果两种变体都有效,我应该使用其中的哪一种?什么时候我应该更喜欢其中一种?
  • 第一种语法在shell中使用,第二种使用Java驱动。
  • @MikeB。第一个示例是如何在 Javascript 中创建唯一索引,第二个示例是如何在 Java 中执行完全相同的操作。因为索引创建是一次性操作,您当然可以使用 Javascript 在 MongoDB shell 中设置索引,但我建议在启动时在 Java 应用程序中进行,因为它使部署更容易。当完全相同的索引已经存在时,createIndex 是空操作。
【解决方案2】:

Phillip 的帮助下,我为 MongoDB 3.2 中的“如何避免重复/插入时跳过重复”问题编写了一个完全可行的解决方案,用于 Java 驱动程序 3.2.0

    IndexOptions options = new IndexOptions();

    // ensure the index is unique
    options.unique(true);
    // define the index
    dbColl.createIndex(new BasicDBObject("guid", 1), options);

    // add data to DB
    for (Object item : itemsArr) {

        // if there is a duplicate, skip it and write to a console (optionally)
        try {
            dbColl.insertOne(Document.parse(item.toString()));
        } catch (com.mongodb.MongoWriteException ex) {
            //System.err.println(ex.getMessage());
        }
    }

请随意使用这个即用型解决方案。

【讨论】:

    猜你喜欢
    • 2018-08-08
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2019-02-05
    • 2018-03-17
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    相关资源
    最近更新 更多