web-dev-qa-db-fra.com

Mongodb éviter les entrées en double

Je suis un débutant à Mongodb. Puis-je savoir comment éviter les entrées en double? Dans les tables relationnelles, nous utilisons la clé primaire pour l'éviter. Puis-je savoir comment le spécifier dans Mongodb en utilisant Java?

25
Jessie

Utilisez un index avec l'option {unique:true}.

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

Vous pouvez également le faire sur plusieurs champs. Voir cette section dans la documentation pour plus de détails et des exemples.

Les index MongoDB peuvent éventuellement imposer une contrainte de clé unique , qui garantit qu'aucun document n'est inséré et que les valeurs des clés indexées ne correspondent à celles d'un document existant.

Si vous souhaitez que les valeurs null soient ignorées de la clé unique, vous devez également rendre l'index clairsemé (see here), en ajoutant également l'option 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});

Si vous souhaitez créer l'index à l'aide du pilote Java MongoDB. Essayer:

Document keys = new Document("email", 1);
collection.createIndex(keys, new IndexOptions().unique(true));
40
theon

Cela peut être fait en utilisant le champ "_id" bien que cette utilisation soit déconseillée . Supposons que vous vouliez que les noms soient uniques, alors vous pouvez les mettre dans la colonne "_id" et comme vous le savez peut-être, la colonne "unique" est unique chaque entrée.

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

Désormais, aucune autre entrée ne peut avoir le nom "amit" dans la collection. Cela peut être une des manières que vous demandez.

1
Amit Chahar

À partir du pilote Java v3.0 de Mongo, le code permettant de créer l'index ressemble à ceci:

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"));
    }
}
1
Cuga

Je ne suis pas un programmeur Java, mais vous pouvez probablement le convertir.

Par défaut, MongoDB a une clé primaire appelée _id. Vous pouvez utiliser upsert() ou save() sur cette clé pour empêcher le document d'être écrit deux fois, comme ceci:

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

Cela arrêtera immédiatement les doublons. En ce qui concerne les inserts multithread sûrs sous certaines conditions: eh bien, nous aurions besoin d'en savoir plus sur votre condition dans ce cas.

Je devrais ajouter cependant que l'index _id est unqiue par défaut.

0
Sammaye

La solution Theon n'a pas fonctionné pour moi, mais celui-ci a fait:

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