2014-07-02 6 views
5

तो मैं किसी ऐप कुछ विन्यास की जानकारी संग्रहीत करने की आवश्यकता है, और इसलिए मैं मोंगो में सरल JSON दस्तावेज़ के रूप में कॉन्फ़िगरेशन भंडारण पर योजना बना रहा हूँ: जैसेमोंगो से/से संस्करणित ऑब्जेक्ट/JSON मैपिंग?

appConfig: { 
    fizz: true, 
    buzz: 34 
} 

इस नक्शे को हो सकता है एक जावा POJO/संस्था के लिए:

public class AppConfig { 
    private boolean fizz; 
    private int buzz; 
} 

इत्यादि। आमतौर पर, संबंधपरक डेटाबेस के साथ, मैं तालिका डेटा से/जावा इकाइयों से ओ/आर मैपिंग के लिए हाइबरनेट/जेपीए का उपयोग करता हूं। I मानते हैं कि तालिका/हाइबरनेट के निकटतम JSON/Mongo साथी एक मॉर्फिया/जीएसओएन कॉम्बो है: मॉर्फिया का उपयोग अपने जावा ऐप से मोंगो से कनेक्टिविटी ड्राइव करने के लिए करें, और उसके बाद जीएसओएन को ओ/जे मैप को जावा पीओजेओ/संस्थाओं।

समस्या यह है कि, समय के साथ, मेरे appConfig दस्तावेज़ संरचना बदलेगी।

appConfig: { 
    fizz: true, 
    buzz: 34 
    foo: "Hello!" 
} 

कौन सा तो POJO/संस्था की आवश्यकता होगी बनने के लिए:: यह की तरह कुछ सरल किया जा सकता

public class AppConfig { 
    private boolean fizz; 
    private int buzz; 
    private String foo; 
} 

लेकिन समस्या यह है मैं JSON दस्तावेज़ पहले से ही में संग्रहीत की हजारों हो सकता है मोंगो जिसमें foo उनके पास संपत्ति नहीं है।

public class AppConfig { 
    private boolean fizz; 
    private int buzz; 
    private String foo = "Hello!" 
} 

हालांकि वास्तविकता में, अंत में AppConfig दस्तावेज़/स्कीमा/संरचना यह है कि कोई रास्ता नहीं है, आकार या रूप में इतना बदल सकता है: इस विशिष्ट मामले में, स्पष्ट समाधान की तरह संपत्ति पर एक डिफ़ॉल्ट सेट करने के लिए है इसके मूल डिजाइन जैसा दिखता है। लेकिन किकर है: मुझे पीछे की ओर संगत होने की आवश्यकता है और, अधिमानतः, जहां उचित हो, नई स्कीमा/संरचना से मेल खाने के लिए दस्तावेजों को अद्यतन/बदलने में सक्षम होना चाहिए।

मेरा प्रश्न: यह "संस्करणित दस्तावेज़" समस्या आमतौर पर हल कैसे होती है?

उत्तर

1

मुझे लगता है कि नीचे धागा तुम्हारी मदद करेगा, हालांकि यह DB में दस्तावेजों वर्ज़निंग के बारे में नहीं है, और यह वसंत-डेटा-MongoDB का उपयोग किया गया है,

How to add a final field to an existing spring-data-mongodb document collection?

तो तुम को मान निर्दिष्ट कर सकते हैं कनवर्टर कार्यान्वयन का उपयोग कर दस्तावेज़ में संपत्ति के अस्तित्व के आधार पर POJO।

+0

धन्यवाद @Lucky सांकेतिक शब्दों में बदलनेवाला (+1) के साथ मदद कर सकता है, लेकिन उस संस्करण परिवर्तन से निपटने जेपीए के साथ संयोजन के रूप में स्कीमा दस्तावेज़ के लिए की तुलना में अंतिम क्षेत्रों के बारे में अधिक हो रहा है। – IAmYourFaja

1

आपके पास मॉर्फिया के साथ कम से कम कुछ विकल्प हैं। आप वर्जन क्लास नाम का उपयोग कर सकते हैं, फिर सही वर्ग संस्करण लाने के लिए क्लासनाम संपत्ति के मॉर्फिया के उपयोग पर भरोसा करें। फिर आपके आवेदन को उस पुराने ऑब्जेक्ट को नई कक्षा परिभाषा में माइग्रेट करना होगा। एक अन्य विकल्प @PreLoad का उपयोग करना है और मॉर्फिया DBObject को अपनी कक्षा में DBObject से पहले नए आकार में मोंगो से बाहर आने वाले DBObject मालिश करें। कक्षा पर एक संस्करण फ़ील्ड का उपयोग करके आप निर्धारित कर सकते हैं कि डेटा लोड होने पर कौन सा माइग्रेशन चलाना है। उस बिंदु से, यह सिर्फ मॉर्फिया के नए रूप की तरह दिखता है और निर्बाध रूप से मानचित्र करेगा। एक बार जब आप उस कॉन्फ़िगरेशन ऑब्जेक्ट को वापस मोंगो में सहेज लेंगे, तो यह नए रूप में होगा और अगले लोड को माइग्रेशन चलाने की आवश्यकता नहीं होगी।

5

मैं आमतौर पर संग्रह में प्रत्येक दस्तावेज़ में एक संस्करण फ़ील्ड जोड़कर इस समस्या को हल करता हूं।

आप AppConfig संग्रह में कई दस्तावेजों हो सकता है:

{ 
    _id: 1, 
    fizz: true, 
    buzz: 34 
} 

{ 
    _id: 2, 
    version: 1, 
    fizz: false, 
    buzz: 36, 
    foo: "Hello!" 
} 

{ 
    _id: 3, 
    version: 1, 
    fizz: true, 
    buzz: 42, 
    foo: "Goodbye" 
} 

उपरोक्त उदाहरण में, वहाँ संस्करण एक पर दो दस्तावेज, और संस्करण शून्य (इस पद्धति में कम से एक पुराने दस्तावेज़ हैं, मैं आम तौर पर एक व्याख्या गुम या शून्य संस्करण फ़ील्ड संस्करण शून्य होने के लिए, क्योंकि मैं हमेशा उत्पादन में दस्तावेजों द्वारा संस्करण बना रहा हूं, क्योंकि मैं हमेशा इसे जोड़ता हूं)।

इस पैटर्न के दो सिद्धांतों:

  1. दस्तावेज हमेशा नवीनतम संस्करण में सहेजे जाते हैं जब वे वास्तव में संशोधित कर रहे हैं।
  2. जब कोई दस्तावेज़ पढ़ा जाता है, यदि यह नवीनतम संस्करण में नहीं है, तो यह पारदर्शी रूप से नवीनतम संस्करण में अपग्रेड हो जाता है।

आप संस्करण काफी नया नहीं है जब संस्करण क्षेत्र की जाँच, और प्रदर्शन एक प्रवास ऐसा करते हैं:

DBObject update(DBObject document) { 
    if (document.getInt("version", 0) < 1) { 
     document.put("foo", "Hello!"); //add default value for foo 
     document.put("version", 1); 
    } 
    return document; 
} 

इस माइग्रेशन काफी आसानी से, मूलभूत मूल्यों के साथ फ़ील्ड जोड़ सकते हैं क्षेत्रों नाम बदलें, और खेतों को हटा दें। चूंकि यह एप्लिकेशन कोड में स्थित है, इसलिए आप आवश्यकतानुसार अधिक जटिल गणना कर सकते हैं।

एक बार दस्तावेज़ माइग्रेट हो जाने के बाद, आप इसे ओडीएम समाधान के माध्यम से चला सकते हैं जिसे आप जावा ऑब्जेक्ट्स में कनवर्ट करना चाहते हैं। इस समाधान को अब संस्करण के बारे में चिंता करने की ज़रूरत नहीं है, क्योंकि जिन दस्तावेज़ों से यह संबंधित है वे सभी वर्तमान हैं!

मॉर्फिया के साथ यह @PreLoad एनोटेशन का उपयोग करके किया जा सकता है।

दो चेतावनियां:

  1. कभी कभी तुम वापस डेटाबेस के लिए तुरंत अपग्रेड दस्तावेज़ को बचाने के लिए कर सकते हैं। इसके लिए सबसे आम कारण हैं जब प्रवास महंगा है, माइग्रेशन गैर-निर्धारिती है या किसी अन्य डेटाबेस के साथ एकीकृत है, या आप पुराने संस्करण को अपग्रेड करने के लिए जल्दी में हैं।

  2. प्रश्नों में मानदंड के रूप में उपयोग किए जाने वाले फ़ील्ड को जोड़ना या नाम बदलना थोड़ा मुश्किल है। अभ्यास में, आपको एक से अधिक क्वेरी करने की आवश्यकता हो सकती है, और परिणामों को एकजुट कर सकते हैं।

मेरी राय में, इस पद्धति MongoDB के महान लाभ में से एक पर प्रकाश डाला गया: के बाद से दस्तावेज आवेदन में संस्करणीकृत रहे हैं, आप मूल डेटा अभ्यावेदन आवेदन में किसी भी ऑफ़लाइन बिना "माइग्रेशन चरण" माइग्रेट कर सकते हैं की तरह क्या तुम करोगी एक एसक्यूएल डेटाबेस के साथ की जरूरत है।

2

JSON deserialzer आप के लिए एक बहुत ही सरल तरीके से इस को हल करती है, (जावा का प्रयोग करके)

बस अपने POJO/संस्था नई फ़ील्ड हो गई करने के लिए अनुमति देते हैं। जब आप अपने JSON को mongo से इकाई में deserialize करते हैं - सभी गायब फ़ील्ड शून्य हो जाएंगे।यह आबादी वाले हो जाएगा -

mongoDocument v3  :  Entity of v1 
    { 
     fizz:"abc",  -->  fizz  = "abc"; 
     buzz:123,   -->  buzz  = 123; 
     newObj:"zzz",  -->  
     obj_v3:"b   -->  

    } 

निर्भर करता है अगर वे खेतों या नहीं:

mongoDocument v1 :  Entity of v3 
    { 
     fizz="abc",  -->  fizz  = "abc"; 
     buzz=123   -->  buzz  = 123; 
         -->  newObj = null; 
         -->  obj_v3 = null; 

    } 

आप भले ही आप आप विरासत सर्वर नए डेटाबेस वस्तुओं के साथ काम करना चाहते आसपास इस दूसरी तरह उपयोग कर सकते हैं deserializer द्वारा। ध्यान रखें कि बूलियन इस के लिए सबसे उपयुक्त नहीं हैं क्योंकि वे गलत पर डिफ़ॉल्ट हो सकते हैं (आप जिस deserializer का उपयोग करते हैं उसके आधार पर)।

तो जब तक कि आप सक्रिय रूप से अपनी ऑब्जेक्ट्स के वर्जनिंग के साथ काम नहीं कर रहे हैं, तब तक जब आप एक विरासत सुरक्षित सर्वर कार्यान्वयन कर सकते हैं तो केवल कुछ नल चेक के साथ किसी भी पुराने ऑब्जेक्ट को संभाल सकता है।

मुझे आशा है कि इस प्रस्ताव को अपने सेट अप