2011-08-25 14 views
8

mongo belgelerinde "Bir belge benzersiz dizine sahip bir koleksiyona kaydedildiğinde, eksik dizinlenmiş anahtarlar boş değerlerle eklenecektir. Bu nedenle, aynı dizine sahip anahtarın eksik olduğu birden çok belgenin eklenmesi mümkün olmayacaktır."Eksik değerleri mongo db kullanarak benzersiz bir dizinde nasıl elde edersiniz?

İsteğe bağlı bir alanda benzersiz bir dizin oluşturmak imkansız mı? Bunu çözmek için bir userId ile bir bileşik indeks oluşturmalı mıyım? Benim özel durumumda, isteğe bağlı yerleşik bir oauth nesnesine sahip bir kullanıcı koleksiyonum var. , ör.

>db.users.ensureIndex({ "name":1, "oauthConnections.provider" : 1, "oauthConnections.providerId" : 1 }); 

Benim örnek kullanıcı Bu isteğe bağlı bir alan indeksine imkansız değil

{ name: "Bob" 
    ,pwd: "myPwd" 
    ,oauthConnections [ 
     { 
     "provider":"Facebook", 
     "providerId" : "12345", 
     "key":"blah" 
     } 
    ,{ 
     "provider":"Twitter", 
     "providerId" : "67890", 
     "key":"foo" 
     } 
    ] 
} 

cevap

11

bunun mümkün olduğuna inanıyoruz: Eğer seyrek ve benzersiz olan bir dizin olabilir. Bu şekilde, varoluş olmayan değerler asla endekse yapmazlar, dolayısıyla çift olamazlar.

Savurma: Bu, bileşik indekslerle mümkün değildir. Sorduğun konusunda emin değilim. Bileşik indeksleri ile ilgili dokümantasyonun bir kısmını alıntılıyorsunuz - orada, eksik değerler eklenecek, fakat sorunuzdan sanırım bileşik w/bileşik indeksleri aramıyorsunuz?

İşte bir örnek:

> db.Test.insert({"myId" : "1234", "string": "foo"}); 
> show collections 
Test 
system.indexes 
> 
> db.Test.find(); 
{ "_id" : ObjectId("4e56e5260c191958ad9c7cb1"), "myId" : "1234", "string" : "foo" } 
> 

> db.Test.ensureIndex({"myId" : 1}, {sparse: true, unique: true}); 
> 
> db.Test.insert({"myId" : "1234", "string": "Bla"}); 
E11000 duplicate key error index: test.Test.$myId_1 dup key: { : "1234" } 
> 
> db.Test.insert({"string": "Foo"}); 
> db.Test.insert({"string": "Bar"}); 
> db.Test.find(); 
{ "_id" : ObjectId("4e56e5260c191958ad9c7cb1"), "myId" : "1234", "string" : "foo" } 
{ "_id" : ObjectId("4e56e5c30c191958ad9c7cb4"), "string" : "Foo" } 
{ "_id" : ObjectId("4e56e5c70c191958ad9c7cb5"), "string" : "Bar" } 

Ayrıca compound indexes can't be sparse

+1

Güzel, hatta belgelendi: "Eksik alanları olan belgeleri yok sayan benzersiz bir kısıtlama oluşturmak için seyrek ile benzersiz birleştirme yapabilirsiniz." – MrKurt

+0

Başka bir soru, eğer seyrek bileşik indeksleriniz yoksa, gömülü bir nesne veya yuvalanmış alan üzerinde seyrek bir dizininiz olabilir mi? Yukarıdaki örnekte, gömülü oauthConnections koleksiyonunda bir dizin olmasını isterdik. – MonkeyBonkey

2

. Dokümanlar, bir benzersiz dizini hakkında konuşuyor. Benzersiz bir dizin belirttikten sonra, bu değer boş olsa bile, yalnızca o alan için değer başına bir belge ekleyebilirsiniz.

İsteğe bağlı bir alan üzerinde benzersiz bir dizin istiyorsanız, ancak yine de birden çok boş değere izin verirseniz, mümkün olup olmadığına dair bir fikrim olmamasına rağmen, dizini hem benzersiz hem de seyrek yapmaya çalışabilirsiniz. Belgelere bir cevap bulamadım.

+0

yup, ben isteğe bağlı bir alan üzerinde benzersiz bir dizin yaratmak istedik söyleyerek daha spesifik olması gerekirdi unutmayın. – MonkeyBonkey

1

İsteğe bağlı bir alanı benzersiz şekilde dizine eklemenin iyi bir yolu yoktur. Bunu bir varsayılan ile doldurabilirsiniz (kullanıcının _id'i çalışacaktır), erişim katmanınızın benzersiz olmasını sağlayın ya da "şemasını" biraz değiştirin.

Kısmen bu nedenle, oauth giriş belirteçleri için ayrı bir koleksiyona sahibiz. Katıştırılmış dokümanlar olarak sahip olmanın bariz bir kazanca sahip olduğu bir bağlamda bunlara asla erişmemiz gerekmez. Bu, yapılacak nispeten kolay bir değişiklikse, muhtemelen en iyi bahistir.

---- düzenleme ---- diğer cevaplar noktaları olarak

, bir seyrek indeksi bunu başarabilirsiniz. Hatta belgelenmiş bir kullanım. Muhtemelen benimkilerden bir tanesini kabul etmelisin.

http://www.mongodb.org/display/DOCS/Indexes#Indexes-SparseIndexes

İlgili konular