Mongodb избегайте дублирования записей

Я новичок в монгодб. Могу ли я узнать, как избежать дублирования записей. В реляционных таблицах мы используем первичный ключ, чтобы этого избежать. Могу ли я узнать, как указать это в Mongodb с помощью java?


person Jessie    schedule 30.08.2012    source источник


Ответы (6)


Используйте индекс с опцией {unique:true}.

// everyone's username must be unique:
db.users.createIndex({email:1},{unique:true});

Вы также можете сделать это в нескольких полях. Дополнительные сведения см. в этом разделе документации. детали и примеры.

Уникальный индекс гарантирует, что в проиндексированных полях не будут храниться повторяющиеся значения; то есть обеспечивает уникальность для индексированных полей. По умолчанию MongoDB создает уникальный индекс в поле _id во время создания коллекции.

Если вы хотите, чтобы значения null из уникального ключа игнорировались, вам также необходимо сделать индекс разреженным (см. здесь), также добавив параметр sparse:

// everyone's username must be unique,
//but there can be multiple users with no email field or a null email:
db.users.createIndex({email:1},{unique:true, sparse:true});

Если вы хотите создать индекс с помощью Java-драйвера MongoDB. Пытаться:

Document keys = new Document("email", 1);
collection.createIndex(keys, new IndexOptions().unique(true));
person theon    schedule 30.08.2012
comment
Примечание. null и ни один из существующих также считается уникальными значениями, поэтому, если у вас есть таблица пользователей, некоторые из которых удалены, и по закону вы удаляете их данные, но сохраняете их строку для удаления в будущем, у вас возникнут проблемы с уникальными индексами. Я думаю, это действительно нужно. - person Sammaye; 30.08.2012
comment
@Sammaye: вы можете использовать разреженные индексы, чтобы решить эту проблему. с нулевыми/отсутствующими полями. - person Stennie; 30.08.2012
comment
+1 Это упоминается в документах здесь, последний абзац для уникальных индексов: docs. mongodb.org/manual/core/indexes/#unique-index - person theon; 30.08.2012
comment
@Stennie Достаточно честно, я, должно быть, пропустил это дополнение - person Sammaye; 30.08.2012
comment
Я не думаю, что это работает, если вы используете BasicDBObject(...).append(...). Уникальный ключ/значение должен находиться в отдельном объекте DBObject. Приведенный выше код попытается создать индекс по ключам электронной почты и уникальности. - person viking; 15.04.2015
comment
Этот подход, по-видимому, основан на реляционном мышлении и, кажется, противоречит понятию mongodb о неструктурированном наборе документов. (Я понимаю, что это из их собственных документов) Установка уникального индекса для ключа действительно гарантирует, что все документы уникальны, но потенциально предотвращает вставку целых классов уникальных документов в коллекцию. Например, документы с одинаковыми значениями для индексированного ключа (ов), но разными значениями для других неиндексированных ключей. Есть ли способ избежать дублирования документов в монго, который не накладывает никакой структуры на документы в коллекции? - person Allen; 08.08.2015
comment
Кажется, это лучшее решение, которое мне удалось найти: stackoverflow.com/a/24125275/1495011 - person Allen; 09.08.2015
comment
@viking Вы правы. Я исправил пример Java. - person theon; 04.02.2016
comment
Примечание: mongodb не может гарантировать уникальность вторичных ключей в осколках! docs.mongodb.com/manual/reference/limits / - person Andy; 18.07.2016
comment
В Mongo 3.x ensureIndex устарел и не рекомендуется: stackoverflow.com/a/30314946/846193 - person Jinesh; 10.08.2016
comment
@ Джинеш Спасибо. Обновленный ответ. - person theon; 10.08.2016

Это можно сделать с помощью поля «_id», хотя такое использование не рекомендуется. предположим, вы хотите, чтобы имена были уникальными, тогда вы можете поместить имена в столбец «_id», и, как вы, возможно, знаете, столбец «_id» уникален для каждой записи.

BasicDBObject bdbo = new BasicDBObject("_id","amit");

Теперь никакая другая запись не может иметь имя «амит» в коллекции. Это может быть одним из способов, о которых вы просите.

person Amit Chahar    schedule 24.09.2014

Что касается Java-драйвера Mongo v3.0, код для создания индекса выглядит так:

public void createUniqueIndex() {
    Document index = new Document("fieldName", 1);
    MongoCollection<Document> collection = client.getDatabase("dbName").getCollection("CollectionName");
    collection.createIndex(index, new IndexOptions().unique(true));
}

// And test to verify it works as expected
@Test
public void testIndex() {
    MongoCollection<Document> collection = client.getDatabase("dbName").getCollection("CollectionName");

    Document newDoc = new Document("fieldName", "duplicateValue");
    collection.insertOne(newDoc);

    // this will throw a MongoWriteException
    try {
        collection.insertOne(newDoc);
        fail("Should have thrown a mongo write exception due to duplicate key");
    } catch (MongoWriteException e) {
        assertTrue(e.getMessage().contains("duplicate key"));
    }
}
person Cuga    schedule 13.01.2016

Решение Theon не сработало для меня, но это сработало:

BasicDBObject query = new BasicDBObject(<fieldname>, 1);
collection.ensureIndex(query, <index_name>, true);
person hithwen    schedule 31.01.2013

Я не программист на Java, но вы, вероятно, можете преобразовать это.

MongoDB по умолчанию имеет первичный ключ, известный как _id, вы можете использовать upsert() или save() для этого ключа, чтобы предотвратить повторную запись документа следующим образом:

var doc = {'name': 'sam'};
db.users.insert(doc); // doc will get an _id assigned to it
db.users.insert(doc); // Will fail since it already exists

Это немедленно остановит дубликаты. Что касается многопоточных безопасных вставок при определенных условиях: ну, в этом случае нам нужно больше знать о вашем состоянии.

Однако я должен добавить, что индекс _id по умолчанию уникален.

person Sammaye    schedule 30.08.2012

используя pymongo, это выглядит так:

mycol.create_index("id", unique=True)

где myCol — коллекция в БД

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pymongo

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]
mycol.create_index("id", unique=True)
mydict = {"name": "xoce", "address": "Highway to hell 666", "id": 1}
x = mycol.insert_one(mydict)
person ΦXocę 웃 Пepeúpa ツ    schedule 28.05.2019