नेगोस्टेड सबमेडिशन बनाम नेस्टेड स्कीमा


122

मैं अपने मुख्य स्कीमा में एक गहरी परत बनाम सबडिमेक्शंस का उपयोग करने के पेशेवरों और विपक्षों के लिए उत्सुक हूं:

var subDoc = new Schema({
  name: String
});

var mainDoc = new Schema({
  names: [subDoc]
});

या

var mainDoc = new Schema({
  names: [{
    name: String
 }]
});

मैं वर्तमान में हर जगह सबडॉक्स का उपयोग कर रहा हूं, लेकिन मैं मुख्य रूप से प्रदर्शन या मेरे द्वारा सामना किए जाने वाले मुद्दों के बारे में सोच रहा हूं।


मैं आपको इसका उत्तर देने के लिए टाइप करने की कोशिश कर रहा था, लेकिन मैं ऐसा नहीं कर पाया। लेकिन यहाँ एक नज़र डालें: mongoosejs.com/docs/subdocs.html
gustavohenke

यहां अपना डेटाबेस स्कीमा बनाते समय खुद से पूछने के लिए MongoDB के विचारों के बारे में एक अच्छी प्रतिक्रिया है: stackoverflow.com/questions/5373198/…
anthonylawson

आपका मतलब है कि यह भी _idक्षेत्र का वर्णन करने के लिए आवश्यक है ? मेरा मतलब है, अगर यह सक्षम है तो यह थोड़े स्वचालित नहीं है?
वडकोरक्वेस्ट

किसी को पता है कि क्या _idउपखंड का क्षेत्र अद्वितीय है? (ओ पी के सवाल में 2 तरह से उपयोग कर बनाई गई)
सैतामा

जवाबों:


72

डॉक्स के अनुसार , यह बिल्कुल वैसा ही है। हालाँकि, स्कीमा का उपयोग करने से एक _idफ़ील्ड और भी जुड़ जाएगा (जब तक आपके पास वह अक्षम नहीं है), और संभवतः सबडॉक्स पर नज़र रखने के लिए कुछ और संसाधनों का उपयोग करता है।

वैकल्पिक घोषणा सिंटैक्स

V3 में नया यदि आपको उप-दस्तावेज़ स्कीमा उदाहरण तक पहुंच की आवश्यकता नहीं है, तो आप बस एक वस्तु शाब्दिक रूप से पास करके उप-डॉक्स की घोषणा कर सकते हैं [...]


1
लेकिन मैंने यह कोशिश की। सब डॉक्यूमेंट्स का डेटा अलग-अलग कलेक्शन में क्यों स्टोर नहीं किया जाता है। यह हमेशा मेनडॉक संग्रह के अंदर संग्रहीत करता है।
फेजर खान

17
कि उप दस्तावेज़ कैसे काम करते हैं। वे एक दस्तावेज़ के अंदर एम्बेड कर रहे हैं। मानस के साथ खेलने से पहले, सुनिश्चित करें कि आप अंतर्निहित MongoDB को समझते हैं।
एंडीएल

1
स्कीमा के बारे में _id को जोड़ने से, यह समझ में आता है, लेकिन मैंने उप-डॉक्स की एक सरणी के साथ एक स्कीमा बनाया और ऑब्जेक्ट लीटर का एक सरणी और दोनों में एक _id जोड़ा गया। व्यवहार बदल गया है?
ड्रू गुडविन

@DrewGoodwin ऐसा लगता है कि यह कुछ समय के लिए ऐसा ही रहा है: stackoverflow.com/questions/17254008/…
cheesemacfly

37

यदि आपके पास अपने मॉडल के विभिन्न भागों में फिर से उपयोग किए जाने वाले स्कीमा हैं, तो यह बच्चे के डॉक्स के लिए अलग-अलग स्कीमा को परिभाषित करने के लिए उपयोगी हो सकता है, ताकि आपको खुद को डुप्लिकेट न करना पड़े।


4
यह एक बेहतरीन जवाब है। कभी-कभी मैं अधिक मॉडल में उप-मॉडल का उपयोग करता हूं, या मेरे पास एक मॉडल में दो फ़ील्ड हैं जिन्हें अलग करने की आवश्यकता है, लेकिन फिर भी एक ही उप-डिज़ाइन संरचना है।
मार्टिन हॉलन

2
आपको अनावश्यक जानकारी को बचाने के लाभ / नुकसान पर भी विचार करना चाहिए।
सैम व्लोबार्ग्स

25

आपको एम्बेडेड दस्तावेजों का उपयोग करना चाहिए यदि वे स्थिर दस्तावेज हैं या जो प्रदर्शन प्रभाव के कारण कुछ सौ से अधिक नहीं हैं। मैं थोड़ी देर पहले उस मुद्दे से गुज़रा हूँ। नव्या, मोंगाडीबी के लिए एक समाधान वास्तुकार के रूप में काम करने वाली आशा काम्स्की ने "सबडिमेक्शंस का उपयोग" के बारे में एक लेख लिखा था।

मुझे उम्मीद है कि जो समाधान या सर्वोत्तम अभ्यास की तलाश कर रहा है वह मदद करता है।

Http://askasya.com/post/largeembeddedays पर मूल पोस्ट । आप https://stackoverflow.com/users/431012/asya-kamsky पर उसके स्टैकओवरफ़्लो प्रोफ़ाइल तक पहुँच सकते हैं

सबसे पहले, हमें विचार करना होगा कि हम ऐसा क्यों करना चाहते हैं। आम तौर पर, मैं लोगों को उन चीजों को एम्बेड करने की सलाह दूंगा जो वे हमेशा इस दस्तावेज को लाने के बाद वापस प्राप्त करना चाहते हैं। इसका दूसरा पहलू यह है कि आप दस्तावेज़ में उन चीजों को एम्बेड नहीं करना चाहते हैं जिन्हें आप वापस नहीं लाना चाहते हैं।

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

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

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

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

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


3
यह शीर्ष उत्तर होना चाहिए; यह पैसे पर धमाका है। MongoDB के खुद के श्वेत पत्र बहुत कुछ एक ही बात कहते हैं।
जे एडवर्ड्स

बकेट पैटर्न के बारे में यह लेख तारीफ करता है कि आसिया क्या बात करती है। mongodb.com/blog/post/building-with-patterns-the-bucket-pattern मुझे लगता है कि ओपी के प्रश्न में उपडोक स्कीमा बकेट पैटर्न के साथ अच्छा काम करेगा।
plong0

13

मूल रूप से, एक चर बनाएं nestedDovऔर इसे यहां रखेंname: [nestedDov]

सरल संस्करण:

var nestedDoc = new Schema({
  name: String
});

var mainDoc = new Schema({
  names: [nestedDoc]
});

JSON उदाहरण

{
    "_id" : ObjectId("57c88bf5818e70007dc72e85"),
    "name" : "Corinthia Hotel Budapest",
    "stars" : 5,
    "description" : "The 5-star Corinthia Hotel Budapest on the Grand Boulevard offers free access to its Royal Spa",
    "photos" : [
        "/photos/hotel/corinthiahotelbudapest/1.jpg",
        "/photos/hotel/corinthiahotelbudapest/2.jpg"
    ],
    "currency" : "HUF",
    "rooms" : [
        {
            "type" : "Superior Double or Twin Room",
            "number" : 20,
            "description" : "These are some great rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/2.jpg",
                "/photos/room/corinthiahotelbudapest/5.jpg"
            ],
            "price" : 73000
        },
        {
            "type" : "Deluxe Double Room",
            "number" : 50,
            "description" : "These are amazing rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/4.jpg",
                "/photos/room/corinthiahotelbudapest/6.jpg"
            ],
            "price" : 92000
        },
        {
            "type" : "Executive Double Room",
            "number" : 25,
            "description" : "These are amazing rooms",
            "photos" : [
                "/photos/room/corinthiahotelbudapest/4.jpg",
                "/photos/room/corinthiahotelbudapest/6.jpg"
            ],
            "price" : 112000
        }
    ],
    "reviews" : [
        {
            "name" : "Tamas",
            "id" : "/user/tamas.json",
            "review" : "Great hotel",
            "rating" : 4
        }
    ],
    "services" : [
        "Room service",
        "Airport shuttle (surcharge)",
        "24-hour front desk",
        "Currency exchange",
        "Tour desk"
    ]
}

उदाहरण:

यहां छवि विवरण दर्ज करें


1
यह उस प्रश्न को बिल्कुल भी संबोधित नहीं करता है जो प्रदर्शन में से एक है।
साइबरवॉम्बट

अधिक समझ बनाने के लिए मैंने थोड़ा सा संपादन किया है। तुम क्या सोचते हो?
वेन चिउ

3
सवाल यह नहीं पूछ रहा है कि नेस्टेड स्कीमा कैसे करें। इसकी चर्चा इस बात पर है कि क्या नेगोस्टेड नेस्टेड स्कीमा या एम्बेडेड उप दस्तावेजों के साथ अधिक प्रदर्शनकारी है। मूल रूप से हम मानदंड या प्रकार या किनारे के मामलों पर बात कर रहे हैं जहां मोंगोज़ एक से दूसरे को पसंद करते हैं। और जैसा कि चयनित उत्तर का उल्लेख है, यह कम से कम V3 पर कोई अंतर नहीं करता है।
साइबरबॉम्बट

17
शायद ओपी के लिए काम नहीं करता है, लेकिन मुझे यह बहुत मददगार लगा। धन्यवाद।
जीन हिगिन्स

यह अच्छा है जब सभी 3 स्कीमा को एक .js फ़ाइल में घोषित किया जाता है, तो हम इसे 3 .js फ़ाइलों में घोषित किए जाने पर कैसे संभाल सकते हैं?
सत्यम

9

मुझे लगता है कि यह SO पर कई पोस्ट द्वारा कहीं और संभाला गया है।

बस थोड़ा सा:

बड़ी कुंजी यह है कि यहां कोई एकल उत्तर नहीं है, केवल जटिल व्यापार-अप का एक सेट है।


3
शायद मैं अपने सवाल को सही ढंग से नहीं बता रहा हूं - यह सवाल नहीं है कि मुझे अपने डेटाबेस को कैसे तैयार करना चाहिए, बल्कि एक उप-विषय का उपयोग करने के आंतरिक बनाम केवल एक गहरी परत में सरणी लिखना है। उपसमूह का उपयोग करने के लिए मेरा प्राथमिक कारण यह है कि मैं कस्टम स्कीमा प्रकारों का उपयोग कर सकता हूं और उन्हें मान्य कर सकता हूं - ऐसा कुछ जो नेस्टेड सरणियों के साथ काम नहीं करता है (पिछले प्रश्न से मैं एसओ पर था)। पास के रूप में मैं बता सकता हूँ कि एक उपखंड एक नेस्टेड सरणी के रूप में बहुत अधिक है - मैं बस इसके आंतरिक हिस्से को नहीं जानता - अगर उनका उपयोग करके प्रदर्शन के मुद्दे या इस तरह का निर्माण होगा।
सायबरवॉम्बैट

0

दोनों के बीच कुछ अंतर हैं:

  • नेस्टेड स्कीमा का उपयोग सत्यापन के लिए सहायक है।

  • नेस्टेड स्कीमा को अन्य स्कीमा में पुन: उपयोग किया जा सकता है।

  • जब तक आप "_id: false" का उपयोग नहीं करते तब तक स्कीमा ने '_id' फ़ील्ड को subdocument में जोड़ दिया है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.