2012-08-04 19 views
5

मैं एक सतत डीबी रखने की कोशिश कर रहा हूं जहां उपयोगकर्ता नाम और ईमेल अद्वितीय हैं।मोंगो डीबी मॉर्फिया - अद्वितीय

http://www.mongodb.org/display/DOCS/Indexes#Indexes-unique%3Atrue

http://code.google.com/p/morphia/wiki/EntityAnnotation

मेरे उपयोगकर्ता वर्ग इस तरह दिखता है:

public class User { 
    @Indexed(unique = true) 
    @Required 
    @MinLength(4) 
    public String username; 

    @Indexed(unique = true) 
    @Required 
    @Email 
    public String email; 

    @Required 
    @MinLength(6) 
    public String password; 

    @Valid 
    public Profile profile; 

    public User() { 
... 

मैं @Indexed (अद्वितीय = true) एनोटेशन का इस्तेमाल किया, लेकिन यह काम नहीं करता। मेरे डीबी में अभी भी डुप्लिकेट हैं।

कोई विचार मैं इसे कैसे ठीक कर सकता हूं?

संपादित करें:

मैं ensureIndexes के बारे में पढ़ा है लेकिन यह एक गलत दृष्टिकोण की तरह, मैं नहीं चाहता कि डुप्लीकेट डेटा अपलोड करने के लिए सिर्फ इतना है कि इसकी वाकई डुप्लिकेट देखना चाहते हैं, लगता है।

मैं इसे तुरंत अवरुद्ध करना चाहता हूं।

try{ 

ds.save(user); 
} 
catch(UniqueException e){ 
... 
} 

उत्तर

1

वहाँ अद्वितीय बाधा के बारे में अच्छी व्याख्या यहीं Unique constraint with JPA and Bean Validation है की तरह somthing, आप बिल्कुल इस मदद करता है? तो मैं अन्य त्रुटियों की जांच करते समय केवल नियंत्रक स्तर (या बीन मान्य()) पर अपने डेटा को सत्यापित करने के लिए क्या करूंगा। वह काम करेगा, लेकिन यह उतना अच्छा नहीं होगा जितना कि एनोटेशन के साथ होगा।

संपादित

वैकल्पिक रूप से इस पोस्ट Inserting data to MongoDB - no error, no insert जो स्पष्ट रूप से है कि MongoDB का वर्णन करता है अद्वितीय इंडेक्सों का डिफ़ॉल्ट रूप से त्रुटि उठाना नहीं पड़ता कि आप ऐसा नहीं बताते, अपने MongoDB को विन्यस्त भी उन त्रुटियों को फेंक करने की कोशिश देख सकते हैं और यदि आप समाधान :(

संपादित 2

यह भी मेरे मन को पार कर गया है कि खेलने के 2 है एक वैश्विक कक्षा शुरू जहाँ आप अपने डेटाबेस का उपयोग करने के लिए कोशिश कर सकते हैं और साथ पर काम कर सकते इस अनुक्रमित कॉलम कमांड को इस db.things.ensureIndex ({ईमेल: 1}, {unique: true}) चलाएं; ?? http://www.playframework.org/documentation/2.0/JavaGlobal

+1

एचएम, मुझे यह नहीं मिला। निश्चित रूप से मैं इसे देख सकता हूं, लेकिन क्या होगा यदि दो उपयोगकर्ता एक ही उपयोगकर्ता नाम के साथ एक ही उपयोगकर्ता नाम पंजीकृत करेंगे? मुझे कुछ ऐसी चीज चाहिए जो परमाणु है। –

+0

डेटाबेस लॉकिंग सिस्टम (पढ़ें, ताले लिखने आदि) में अपना स्वयं का निर्माण है, इसलिए मेरा मानना ​​है कि यदि डेटाबेस स्तर पर अनन्य बाधाएं हैं - एक ही समय में डुप्लिकेट डेटा सहेजना संभव नहीं होगा? –

+0

शायद मैं गलत हूं लेकिन मैंने सोचा कि आपको ऐसा कुछ मतलब है। 'if (user.not_in_db) ds.save (उपयोगकर्ता); 'और यदि मुझे डीबी स्तर पर कोई बाधा नहीं है तो डुप्लिकेट डेटा होगा। –

5

unique index पर बनाया जा सकता है यदि आपके द्वारा इंडेक्स करने की कोशिश कर रहे कॉलम में पहले से ही डुप्लीकेट हैं।

मैं mongo खोल से अपने ensureIndex आदेशों चलाने की कोशिश करेंगे: ..

db.user.ensureIndex({'username':1},{unique:true}) 
db.user.ensureIndex({'email':1},{unique:true}) 

और यह भी जाँचें कि अनुक्रमित सेट कर रहे हैं:

db.user.getIndexes() 

अफ़ीम का सत्त्व WriteConcern.SAFE डिफ़ॉल्ट, द्वारा निर्धारित किया जाना चाहिए था जो एक अद्वितीय इंडेक्स का उल्लंघन करने वाले दस्तावेजों को सम्मिलित करने का प्रयास करते समय अपवाद फेंक देगा।

+0

आप दोनों के लिए धन्यवाद, यही वह है जिसे मैं ढूंढ रहा था। –

+0

यह सही जवाब होना चाहिए। –

0

मुझे प्ले फ्रेमवर्क 1.2.6 और मॉर्फिया 1.2.12 के साथ एक ही समस्या थी।

@Indexed (अद्वितीय = सत्य) एनोटेशन के लिए समाधान है जो मोर्फा को संग्रह बनाने के लिए बनाने के लिए है। इसलिए यदि मेरे पास पहले से ही "खाता" संग्रह था, और ईमेल कॉलम को एनोटेट किया गया था, और प्ले ऐप शुरू कर दिया था, तो खाता इंडेक्स में कुछ भी नहीं बदला गया।

अगर मैं खाता ollection गिरा दिया, अफ़ीम का सत्त्व फिर से यह crated, और अब ईमेल कॉलम अद्वितीय है:

> db.Account.drop() 
true 

खेलने पुनः आरंभ करने के बाद: (मैं प्रारंभिक खाते बनाने के लिए एक नौकरी है ...)

> db.Account.getIndexes() 
[ 
     { 
       "v" : 1, 
       "key" : { 
         "_id" : 1 
       }, 
       "ns" : "something.Account", 
       "name" : "_id_" 
     }, 
     { 
       "v" : 1, 
       "key" : { 
         "email" : 1 
       }, 
       "unique" : true, 
       "ns" : "something.Account", 
       "name" : "email_1" 
     } 
] 

अब, पहले से मौजूद ईमेल के साथ सम्मिलित करने के बाद, मुझे MongoException.DuplicateKey अपवाद मिलता है।

0

इंडेक्स बनाने के लिए, Datastore.ensureIndexes() विधि को मोंगोडीबी को इंडेक्स लागू करने के लिए बुलाया जाना आवश्यक है। मॉर्फिया के साथ अपनी संस्थाओं को पंजीकृत करने के बाद विधि को बुलाया जाना चाहिए। फिर यह आपके इंडेक्स को सिंक्रनाइज़ कर देगा। यह हर बार जब आप अपना आवेदन शुरू करेंगे तो यह किया जाना चाहिए।

Morphia m = ... 
Datastore ds = ... 

m.map(Product.class); 
ds.ensureIndexes(); //creates all defined with @Indexed 
0

मॉर्फिया कक्षा के नाम या @ एंटीटी एनोटेशन वैल्यू के साथ संग्रह के लिए इंडेक्स बनाएगा।

उदाहरण के लिए

यदि आपका वर्ग के नाम लेखक है:

  • कृपया आप इकाई कक्षा में सुनिश्चित करें कि आप @Indexed है एनोटेशन बनाने के लिए और आप इन दो चरणों में किया है:

    m.map(Author.class);

    ds.ensureIndexes();

  • मोंगो डीबी

    पर इंडेक्स जांचें 10

    b.Author.getIndexes()

मैं, इस सवाल का जवाब द्वारा जोड़ा जा रहा पर जोर देना है कि आप एक कस्टम संकलन नाम के साथ अनुक्रमित (इकाई वर्ग लेखक है, लेकिन अपने संग्रह नाम अलग है)

यह परिदृश्य है नहीं बना सकते कई मामलों में स्पष्ट है, जहां आप इकाई वर्ग का पुन: उपयोग करना चाहते हैं यदि स्कीमा समान है