2016-06-23 43 views
5

Ho il seguente schema di JSON in MongoDB:Come posso specificare l'unicità su più campi in mongo, NON combinati?

{"email": "[email protected]", "second_email": "[email protected]"} 

Come posso far rispettare che entrambi i campi sarà unica separatamente e anche essere unica tra di loro.

cioè il seguente documento non sarà valida:

{"email":"[email protected]", "second_email":"[email protected]"} 

Perché [email protected] è già presente in un altro documento nell'altro campo.

risposta

5

In cima alla mia testa, nessun database può eseguire questa operazione (utilizzare un'altra colonna/campo come dati di origine per il vincolo di unicità). Dovrai fare un po 'di rimodellamento dei dati per raggiungere questo obiettivo. Il modo più semplice è un vincolo univoco su un campo array.

> db.foo.createIndex({ emails: 1 }, { unique: true }) 

> db.foo.insert({ emails: ['[email protected]', '[email protected]'] }) 
WriteResult({ "nInserted" : 1 }) 
> db.foo.insert({ emails: ['[email protected]', '[email protected]'] }) 
WriteResult({ 
    "nInserted" : 0, 
    "writeError" : { 
     "code" : 11000, 
     "errmsg" : "E11000 duplicate key error index: test.foo.$emails_1 dup key: { : \"[email protected]\" }" 
    } 
}) 

Ora, a seconda della logica dell'app, questo array di e-mail può anche sostituire i due campi originali. O no. Sta a te. In caso contrario, è necessario inserire entrambi i campi originali e duplicati in questo array per il controllo di unicità.

+1

Dovresti usare 'createIndex' invece di' ensureIndex' – styvane

+1

@ user3100115: oh, nuova API? In che versione è stata introdotta? :) –

+1

Bene 'ensureIndex' è deprecato in 3.0. – styvane

1

È necessario creare un unique index su ciascun campo per applicare l'univocità per i campi.

db.collection.createIndex({ "email": 1 }, { "unique": true }) 
db.collection.createIndex({ "second_email": 1 }, { "unique": true }) 

Detto questo, MongoDB non non fornisce un modo per far rispettare l'unicità per due campi gli stessi documenti. Questo è qualcosa che devi fare nella tua applicazione usando una dichiarazione if/else.

Un'altra opzione come mostrato in questo answer here è quello di utilizzare un campo di matrice indicizzato se non si desidera chiamare i createIndex() metodo più volte. Ma è ancora necessario utilizzare l'elaborazione della condizione logica se non si desidera il valore duplicato nella matrice.

+2

Con la matrice indicizzata, non sono necessari i singoli indici di campo. –

+0

@SergioTulentsev Non potrei essere più d'accordo. – styvane