2011-07-19 16 views
18

I mają strukturę podobną do tej:MongoDB: Unikalny wskaźnik na tablicę elementu własności

class Cat { 
    int id; 
    List<Kitten> kittens; 
} 

class Kitten { 
    int id; 
} 

Chciałbym uniemożliwić użytkownikom tworzenie kota z więcej niż jednego kotka z tym samym identyfikatorem. Próbowałem utworzyć indeks w następujący sposób:

Ale kiedy próbuję wstawić źle sformatowanego kota, Mongo to akceptuje.

Czy brakuje mi czegoś? czy można to nawet zrobić?

+1

Zobacz http://stackoverflow.com/questions/4435637/mongodb-unique-key-in-embedded-document/4437836 – pingw33n

Odpowiedz

24

O ile mi wiadomo, tylko unikatowe indeksy wymuszać unikatowość na różnych dokumentach, więc to byłoby wyrzucić duplikat błędu klucz:

db.cats.insert({ id: 123, kittens: [ { id: 456 } ] }) 
db.cats.insert({ id: 123, kittens: [ { id: 456 } ] }) 

Ale jest to dozwolone: ​​

db.cats.insert({ id: 123, kittens: [ { id: 456 }, { id: 456 } ] }) 

jestem nie jesteś pewien, czy istnieje jakiś sposób wymuszenia ograniczenia na poziomie Mongo, może to coś, co możesz sprawdzić w logice aplikacji po wstawieniu aktualizacji?

+1

niestety wygląda na to, że masz rację - będę musiał wymusić to w kodzie. No cóż. –

+6

Bardzo smutny! :(Powinna istnieć możliwość zapewnienia unikatowości w macierzach dokumentów. –

+0

Co możesz zrobić, to zapisać haki sprawdzania poprawności przy zapisywaniu w tablicy, aby upewnić się, że jest unikatowe. –

21

Zapewnienie niepowtarzalność poszczególnych wartości w polu tablicy

W uzupełnieniu do powyższego przykładu, istnieje funkcja w MongoDB, aby upewnić się, że podczas dodawania nowego obiektu/wartość do tablicy pole, że wykona aktualizację, tylko jeśli wartość/obiekt jeszcze nie istnieje.

Więc jeśli masz dokument, który wygląda tak:

{ _id: 123, kittens: [456] } 

To byłby dozwolony:

db.cats.update({_id:123}, {$push: {kittens:456}}) 

powodując

{ _id: 123, kittens: [456, 456] } 

jednak używając $ addToSet funkcja (w przeciwieństwie do $ pu sh) sprawdzi, czy wartość już istnieje przed dodaniem. Więc, zaczynając od:

{ _id: 123, kittens: [456] } 

następnie wykonanie:

db.cats.update({_id:123}, {$addToSet: {kittens:456}}) 

nie miałoby żadnego wpływu.

Krótko mówiąc, unikalne ograniczenia nie potwierdzają jednoznaczności w elementach wartości pola tablicy, tylko że dwa dokumenty nie mogą mieć identycznych wartości w indeksowanych polach.

1

Istnieje odpowiednik insertu z atrybutem uniquness in array. Poniższe polecenie w zasadzie wstawia się przy jednoczesnym zapewnieniu wyjątkowości kociąt (upsert tworzy je dla ciebie, jeśli obiekt z 123 jeszcze nie istnieje).

db.cats.update(
    { id: 123 }, 
    { $addToSet: {kittens: { $each: [ 456, 456] }}, $set: {'otherfields': 'extraval', "field2": "value2"}}, 
    { upsert: true} 
) 

Uzyskaną wartość przedmiotu będzie

{ 
    "id": 123, 
    "kittens": [456], 
    "otherfields": "extraval", 
    "field2": "value2" 
} 
+0

Ważne właściwości to '$ addToSet' i' upsert'. Właściwość '$ set' nie ma związku z OP. –

Powiązane problemy