2016-06-23 8 views
5

Ich habe folgendes JSON Schema in MongoDB:Wie kann ich die Eindeutigkeit für mehrere Felder in Mongo angeben, NICHT kombiniert?

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

Wie kann ich erzwingen, dass beiden Felder separat eindeutig sein werden und auch zwischen ihnen eindeutig sein.

heißt das folgende Dokument nicht gültig:

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

Da [email protected] ist existiert bereits in einem anderen Dokument in dem anderen Feld.

Antwort

5

In meinem Kopf kann keine Datenbank dies tun (verwenden Sie eine andere Spalte/ein anderes Feld als Quelldaten für die Eindeutigkeitseinschränkung). Sie müssen einige Daten neu gestalten, um dies zu erreichen. Der einfachste Weg ist eine eindeutige Einschränkung für ein Array-Feld.

> 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]\" }" 
    } 
}) 

Jetzt, abhängig von Ihrer App-Logik, kann diese E-Mails-Array sogar Ihre ursprünglichen zwei Felder ersetzen. Oder nicht. Wie du willst. Wenn nicht, müssen Sie die beiden Originalfelder und einfügen, um sie in diesem Array für die Eindeutigkeitsprüfung zu duplizieren.

+1

Btw sollten Sie 'createIndex' statt' sureIndex' verwenden – styvane

+1

@ user3100115: oh, neue API? In welcher Version wurde es eingeführt? :) –

+1

Nun 'sureIndex' ist in 3.0 veraltet. – styvane

1

Sie müssen für jedes Feld eine unique index erstellen, um die Eindeutigkeit für die Felder zu erzwingen.

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

aber sagen, dass MongoDB bietet keine keine Möglichkeit Einzigartigkeit für zwei Felder in den gleichen Dokumenten zu erzwingen. Dies ist etwas, was Sie in Ihrer Anwendung mit einer if/else Anweisung tun müssen.

Eine weitere Möglichkeit, wie in diesen answer here gezeigt ist, ein indiziert Array-Feld zu verwenden, wenn Sie die createIndex() Methode mehrfach nicht nennen wollen. Sie müssen jedoch weiterhin die Verarbeitung logischer Bedingungen verwenden, wenn Sie keinen doppelten Wert im Array wünschen.

+2

Mit indiziertem Array benötigen Sie nicht die einzelnen Feldindizes. –

+0

@SergioTulentsev Ich könnte mehr nicht zustimmen. – styvane