2012-08-30 15 views
23

Sono novizio di mongodb. Posso sapere come evitare le voci duplicate. Nelle tabelle relazionali, usiamo la chiave primaria per evitarlo. Posso sapere come specificarlo in Mongodb usando java?Mongodb evitare le voci duplicate

risposta

38

Utilizzare un indice con l'opzione {unique:true}.

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

È anche possibile farlo su più campi. Vedere this section nei documenti per ulteriori dettagli ed esempi.

indici MongoDB possono facoltativamente imporre un unico vincolo di chiave, che garantisce che nessun documento vengono inseriti valori cui le chiavi indicizzati corrispondere a quelli di un documento esistente.

Se si desidera per null valori siano ignorati dalla chiave univoca, allora si deve fare anche l'indice di scarsa (vedere here di), aggiungendo anche l'opzione 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}); 

Se si desidera creare l'indice utilizzando il driver Java MongoDB. Prova:

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

Nota: 'null' e nessuno esistente vale come valori univoci quindi se hai una tabella di utenti con alcuni cancellati e per legge rimuovi i loro dati ma mantieni la riga per la cancellazione futura avrai problemi con indici unici. Immagino che sia davvero necessario. – Sammaye

+2

@Sammaye: è possibile utilizzare [sparse indexes] (http://www.mongodb.org/display/DOCS/Indexes#Indexes-sparse%3Atrue) per risolvere il problema con campi nulli/mancanti. – Stennie

+0

+1 È menzionato nei documenti qui, ultimo paragrafo per gli indici unici: http://docs.mongodb.org/manual/core/indexes/#unique-index – theon

0

Non sono un programmatore Java, tuttavia è possibile che si riesca a convertirlo.

MongoDB per default ha ancora una chiave primaria noto come il _id è possibile utilizzare upsert() o save() su questo tasto per evitare che il documento venga scritto due volte in questo modo:

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 

Questo fermerà immediatamente duplicati. Per quanto riguarda gli inserti sicuri multithread in determinate condizioni: beh, avremmo bisogno di sapere di più sulla tua condizione in quel caso.

Devo tuttavia aggiungere che l'indice _id non è corretto per impostazione predefinita.

+0

Perché il downvote? – Sammaye

+0

Typo, sembra ... – Sammaye

0

soluzione Theon non ha funzionato per me, ma questo fatto:

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

Questo può essere fatto utilizzando il campo "_id", anche se questo uso è sconsigliato. Supponiamo che tu voglia che i nomi siano univoci, quindi puoi mettere i nomi nella colonna "_id" e come potresti sapere la colonna "_id" è unica per ogni voce.

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

Ora, nessun altra voce può avere nome come "Amit" nei collection.This può essere uno dei modi si sta chiedendo.

1

A partire dal conducente Java v3.0 di Mongo, il codice per creare l'indice si presenta come:

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")); 
    } 
} 
Problemi correlati