आइए एक बुनियादी अस्वीकरण के साथ शुरू करें जिसमें समस्या का उत्तर देने वाले मुख्य भाग का उत्तर यहां Find पर पहले ही दिया जा चुका है। डबल नेस्टेड ऐरे में MongoDB . और "रिकॉर्ड के लिए" डबल ट्रिपल . पर भी लागू होता है या चौगुनी या कोई भी मूल रूप से एक ही सिद्धांत के रूप में नेस्टिंग का स्तर हमेशा ।
किसी भी उत्तर का दूसरा मुख्य बिंदु यह भी है डोन्ट नेस्ट एरेज़ , क्योंकि जैसा कि उस उत्तर में भी बताया गया है (और मैंने इसे कई . दोहराया है टाइम्स ), जो भी कारण आप "सोचते हैं" आपके पास "घोंसले के शिकार" . के लिए है वास्तव में आपको वह लाभ नहीं देता है जो आप प्राप्त करते हैं। वास्तव में "घोंसला" वास्तव में जीवन को और अधिक कठिन बना रहा है।
नेस्टेड समस्याएं
"रिलेशनल" मॉडल से डेटा संरचना के किसी भी अनुवाद की मुख्य गलत धारणा को हमेशा "नेस्टेड सरणी स्तर जोड़ें" के रूप में व्याख्या किया जाता है। प्रत्येक संबद्ध मॉडल के लिए। आप यहां जो प्रस्तुत कर रहे हैं वह इस गलत धारणा का अपवाद नहीं है क्योंकि यह बहुत हद तक "सामान्यीकृत" प्रतीत होता है ताकि प्रत्येक उप-सरणी में उसके माता-पिता से संबंधित आइटम हों।
MongoDB एक "दस्तावेज़" आधारित डेटाबेस है, इसलिए यह आपको ऐसा करने की अनुमति देता है या वास्तव में कोई भी डेटा संरचना सामग्री जो आप मूल रूप से चाहते हैं। हालांकि इसका मतलब यह नहीं है कि इस तरह के डेटा के साथ काम करना आसान है या वास्तविक उद्देश्य के लिए वास्तव में व्यावहारिक है।
आइए प्रदर्शित करने के लिए कुछ वास्तविक डेटा के साथ स्कीमा भरें:
{
"_id": 1,
"first_level": [
{
"first_item": "A",
"second_level": [
{
"second_item": "A",
"third_level": [
{
"third_item": "A",
"forth_level": [
{
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"price": 1,
"sales_date": new Date("2018-11-01"),
"quantity": 1
},
{
"price": 1,
"sales_date": new Date("2018-11-02"),
"quantity": 1
},
]
},
{
"third_item": "B",
"forth_level": [
{
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
]
}
]
},
{
"second_item": "A",
"third_level": [
{
"third_item": "B",
"forth_level": [
{
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
]
}
]
}
]
},
{
"first_item": "A",
"second_level": [
{
"second_item": "B",
"third_level": [
{
"third_item": "A",
"forth_level": [
{
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
]
}
]
}
]
}
]
},
{
"_id": 2,
"first_level": [
{
"first_item": "A",
"second_level": [
{
"second_item": "A",
"third_level": [
{
"third_item": "A",
"forth_level": [
{
"price": 2,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
}
]
}
]
}
]
}
]
},
{
"_id": 3,
"first_level": [
{
"first_item": "A",
"second_level": [
{
"second_item": "B",
"third_level": [
{
"third_item": "A",
"forth_level": [
{
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
}
]
}
]
}
]
}
]
}
यह प्रश्न में संरचना से "थोड़ा" अलग है लेकिन प्रदर्शन उद्देश्यों के लिए इसमें वे चीजें हैं जिन्हें हमें देखने की आवश्यकता है। मुख्य रूप से दस्तावेज़ में एक सरणी होती है जिसमें उप-सरणी वाले आइटम होते हैं, जिसके बदले में उप-सरणी में आइटम होते हैं और इसी तरह। "सामान्यीकरण" यहाँ निश्चित रूप से प्रत्येक "स्तर" पर पहचानकर्ताओं द्वारा "आइटम प्रकार" या आपके पास वास्तव में जो कुछ भी है।
मूल समस्या यह है कि आप इन नेस्टेड सरणी के भीतर से डेटा का "कुछ" चाहते हैं, और मोंगोडीबी वास्तव में केवल "दस्तावेज़" वापस करना चाहता है, जिसका अर्थ है कि आपको "उप- आइटम"।
"सही ढंग से" . के मुद्दे पर भी इन सभी "उप-मानदंडों" से मेल खाने वाले दस्तावेज़ का चयन करने के लिए $elemMatch
सरणी तत्वों के प्रत्येक स्तर पर स्थितियों का सही संयोजन प्राप्त करने के लिए। आप सीधे "Dot Notation"
का उपयोग नहीं कर सकते उन लोगों की आवश्यकता के कारण एकाधिक शर्तें
. बिना $elemMatch
कथन आपको सटीक "संयोजन" नहीं मिलता है और केवल किसी भी पर शर्त सही होने पर दस्तावेज़ प्राप्त करें सरणी तत्व।
वास्तव में "सरणी सामग्री को फ़िल्टर करना" तो वह वास्तव में अतिरिक्त अंतर का हिस्सा है:
db.collection.aggregate([
{ "$match": {
"first_level": {
"$elemMatch": {
"first_item": "A",
"second_level": {
"$elemMatch": {
"second_item": "A",
"third_level": {
"$elemMatch": {
"third_item": "A",
"forth_level": {
"$elemMatch": {
"sales_date": {
"$gte": new Date("2018-11-01"),
"$lt": new Date("2018-12-01")
}
}
}
}
}
}
}
}
}
}},
{ "$addFields": {
"first_level": {
"$filter": {
"input": {
"$map": {
"input": "$first_level",
"in": {
"first_item": "$$this.first_item",
"second_level": {
"$filter": {
"input": {
"$map": {
"input": "$$this.second_level",
"in": {
"second_item": "$$this.second_item",
"third_level": {
"$filter": {
"input": {
"$map": {
"input": "$$this.third_level",
"in": {
"third_item": "$$this.third_item",
"forth_level": {
"$filter": {
"input": "$$this.forth_level",
"cond": {
"$and": [
{ "$gte": [ "$$this.sales_date", new Date("2018-11-01") ] },
{ "$lt": [ "$$this.sales_date", new Date("2018-12-01") ] }
]
}
}
}
}
}
},
"cond": {
"$and": [
{ "$eq": [ "$$this.third_item", "A" ] },
{ "$gt": [ { "$size": "$$this.forth_level" }, 0 ] }
]
}
}
}
}
}
},
"cond": {
"$and": [
{ "$eq": [ "$$this.second_item", "A" ] },
{ "$gt": [ { "$size": "$$this.third_level" }, 0 ] }
]
}
}
}
}
}
},
"cond": {
"$and": [
{ "$eq": [ "$$this.first_item", "A" ] },
{ "$gt": [ { "$size": "$$this.second_level" }, 0 ] }
]
}
}
}
}},
{ "$unwind": "$first_level" },
{ "$unwind": "$first_level.second_level" },
{ "$unwind": "$first_level.second_level.third_level" },
{ "$unwind": "$first_level.second_level.third_level.forth_level" },
{ "$group": {
"_id": {
"date": "$first_level.second_level.third_level.forth_level.sales_date",
"price": "$first_level.second_level.third_level.forth_level.price",
},
"quantity_sold": {
"$avg": "$first_level.second_level.third_level.forth_level.quantity"
}
}},
{ "$group": {
"_id": "$_id.date",
"prices": {
"$push": {
"price": "$_id.price",
"quanity_sold": "$quantity_sold"
}
},
"quanity_sold": { "$avg": "$quantity_sold" }
}}
])
यह सबसे अच्छा "गन्दा" और "शामिल" के रूप में वर्णित है। $elemMatch के साथ न केवल दस्तावेज़ चयन के लिए हमारी प्रारंभिक क्वेरी है
एक कौर से अधिक, लेकिन फिर हमारे पास बाद में $filter है
और $map
प्रत्येक सरणी स्तर के लिए प्रसंस्करण। जैसा कि पहले उल्लेख किया गया है, यह पैटर्न है चाहे वास्तव में कितने भी स्तर हों।
आप वैकल्पिक रूप से $unwind
कर सकते हैं
और $match
जगह में सरणियों को फ़िल्टर करने के बजाय संयोजन, लेकिन यह पर अतिरिक्त ओवरहेड का कारण बनता है $अनविंड
अवांछित सामग्री को हटाए जाने से पहले, इसलिए MongoDB के आधुनिक रिलीज़ में यह आमतौर पर $फ़िल्टर
पहले सरणी से।
यहां अंतिम स्थान वह है जिसे आप $group
तत्वों द्वारा जो वास्तव में सरणी के अंदर हैं, इसलिए आपको $अनविंड
इससे पहले वैसे भी सरणियों का प्रत्येक स्तर।
वास्तविक "ग्रुपिंग" तब आमतौर पर sales_date
. का उपयोग करके सीधा होता है और कीमत
पहले . के लिए गुण संचय, और फिर एक अनुवर्ती चरण को $pushमें जोड़ना कोड>
अलग कीमत
वे मान जिन्हें आप प्रत्येक तिथि के भीतर सेकंड . के रूप में औसत जमा करना चाहते हैं संचय।
नोट :तिथियों की वास्तविक हैंडलिंग व्यावहारिक उपयोग में अच्छी तरह से भिन्न हो सकती है, जिस पर आप उन्हें स्टोर करते हैं। इस नमूने में तिथियां प्रत्येक "दिन" की शुरुआत के लिए पहले ही गोल कर दी गई हैं। यदि आपको वास्तव में वास्तविक "डेटाटाइम" मान जमा करने की आवश्यकता है, तो आप शायद वास्तव में इस तरह या इसी तरह का निर्माण चाहते हैं:
{ "$group": {
"_id": {
"date": {
"$dateFromParts": {
"year": { "$year": "$first_level.second_level.third_level.forth_level.sales_date" },
"month": { "$month": "$first_level.second_level.third_level.forth_level.sales_date" },
"day": { "$dayOfMonth": "$first_level.second_level.third_level.forth_level.sales_date" }
}
}.
"price": "$first_level.second_level.third_level.forth_level.price"
}
...
}}
$dateFromParts
का इस्तेमाल करना
और अन्य डेट एग्रीगेशन ऑपरेटर
"दिन" की जानकारी निकालने और जमा करने के लिए उस रूप में तारीख को वापस प्रस्तुत करने के लिए।
असामान्यीकरण करना प्रारंभ करें
उपरोक्त "गड़बड़" से क्या स्पष्ट होना चाहिए कि नेस्टेड सरणी के साथ काम करना बिल्कुल आसान नहीं है। ऐसी संरचनाएं आम तौर पर मोंगोडीबी 3.6 से पहले रिलीज में परमाणु रूप से अपडेट करने के लिए भी संभव नहीं थीं, और यहां तक कि अगर आपने उन्हें कभी भी अपडेट नहीं किया या मूल रूप से पूरे सरणी को बदलने के साथ रहते थे, तब भी वे पूछताछ के लिए आसान नहीं हैं। आपको यही दिखाया जा रहा है।
जहां आपको जरूरी मूल दस्तावेज़ में सरणी सामग्री है, आमतौर पर "समतल" . की सलाह दी जाती है और "असामान्यीकृत करें" ऐसी संरचनाएं। यह संबंधपरक सोच के विपरीत प्रतीत हो सकता है, लेकिन वास्तव में प्रदर्शन कारणों से ऐसे डेटा को संभालने का यह सबसे अच्छा तरीका है:
{
"_id": 1,
"data": [
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-01"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-02"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "B",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "B",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "B",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
]
},
{
"_id": 2,
"data": [
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 2,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
}
]
},
{
"_id": 3,
"data": [
{
"first_item": "A",
"second_item": "B",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
}
]
}
यह वही डेटा है जो मूल रूप से दिखाया गया है, फिर भी नेस्टिंग . के बजाय हम वास्तव में प्रत्येक मूल दस्तावेज़ के भीतर सब कुछ एकवचन चपटा सरणी में डालते हैं। निश्चित रूप से इसका अर्थ है दोहराव विभिन्न डेटा बिंदुओं की, लेकिन क्वेरी जटिलता और प्रदर्शन में अंतर स्वयं स्पष्ट होना चाहिए:
db.collection.aggregate([
{ "$match": {
"data": {
"$elemMatch": {
"first_item": "A",
"second_item": "A",
"third_item": "A",
"sales_date": {
"$gte": new Date("2018-11-01"),
"$lt": new Date("2018-12-01")
}
}
}
}},
{ "$addFields": {
"data": {
"$filter": {
"input": "$data",
"cond": {
"$and": [
{ "$eq": [ "$$this.first_item", "A" ] },
{ "$eq": [ "$$this.second_item", "A" ] },
{ "$eq": [ "$$this.third_item", "A" ] },
{ "$gte": [ "$$this.sales_date", new Date("2018-11-01") ] },
{ "$lt": [ "$$this.sales_date", new Date("2018-12-01") ] }
]
}
}
}
}},
{ "$unwind": "$data" },
{ "$group": {
"_id": {
"date": "$data.sales_date",
"price": "$data.price",
},
"quantity_sold": { "$avg": "$data.quantity" }
}},
{ "$group": {
"_id": "$_id.date",
"prices": {
"$push": {
"price": "$_id.price",
"quantity_sold": "$quantity_sold"
}
},
"quantity_sold": { "$avg": "$quantity_sold" }
}}
])
अब उन $elemMatch
को नेस्ट करने के बजाय
कॉल और इसी तरह $filter
के लिए
भाव, सब कुछ बहुत स्पष्ट और पढ़ने में आसान है और वास्तव में प्रसंस्करण में काफी सरल है। इसमें एक और फायदा है कि आप वास्तव में सरणी में तत्वों की कुंजियों को भी अनुक्रमित कर सकते हैं जैसा कि क्वेरी में उपयोग किया गया है। यह नेस्टेड . की एक बाधा थी मॉडल जहां MongoDB ऐसे "मल्टीकी इंडेक्सिंग" सरणी के भीतर सरणियों की कुंजियों पर . एकल सरणी के साथ इसकी अनुमति है और इसका उपयोग प्रदर्शन को बेहतर बनाने के लिए किया जा सकता है।
"सरणी सामग्री फ़िल्टरिंग" . के बाद सब कुछ फिर बिल्कुल वैसा ही रहता है, अपवाद के साथ यह केवल पथ नाम है जैसे "data.sales_date"
लंबे समय तक चलने वाले "first_level.second_level.third_level.forth_level.sales_date"
के विपरीत पिछली संरचना से।
जब एम्बेड न करें
अंत में दूसरी बड़ी गलत धारणा यह है कि सभी संबंध सरणियों के भीतर एम्बेडिंग के रूप में अनुवाद करने की आवश्यकता है। यह वास्तव में कभी भी मोंगोडीबी का इरादा नहीं था और आप केवल उसी दस्तावेज़ के भीतर "संबंधित" डेटा को एक सरणी में रखने के लिए थे, जहां इसका मतलब "जुड़ने" के विपरीत डेटा की एकल पुनर्प्राप्ति करना था।
यहां क्लासिक "ऑर्डर/विवरण" मॉडल आम तौर पर लागू होता है जहां आधुनिक दुनिया में आप "ऑर्डर" के लिए "हेडर" प्रदर्शित करना चाहते हैं जैसे कि ग्राहक का पता, ऑर्डर कुल और इसी तरह के विवरण के रूप में उसी "स्क्रीन" के भीतर विवरण "आदेश" पर विभिन्न पंक्ति वस्तुएँ।
RDBMS की स्थापना के समय में, सामान्य 80 वर्ण गुणा 25 लाइन स्क्रीन में केवल एक स्क्रीन पर ऐसी "हेडर" जानकारी थी, फिर खरीदी गई हर चीज़ के लिए विवरण लाइनें एक अलग स्क्रीन पर थीं। तो स्वाभाविक रूप से अलग-अलग तालिकाओं में संग्रहीत करने के लिए सामान्य ज्ञान का कुछ स्तर था। जैसे-जैसे दुनिया ऐसी "स्क्रीन" पर और अधिक विस्तार में जाती है, आप आमतौर पर पूरी चीज़ देखना चाहते हैं, या कम से कम "हेडर" और ऐसे "ऑर्डर" की पहली इतनी सारी लाइनें।
इसलिए इस तरह की व्यवस्था एक सरणी में डालने के लिए समझ में आता है, क्योंकि मोंगोडीबी एक "दस्तावेज़" देता है जिसमें संबंधित डेटा एक ही बार में होता है। अलग प्रदान की गई स्क्रीन के लिए अलग-अलग अनुरोधों की आवश्यकता नहीं है और ऐसे डेटा पर "जुड़ने" की कोई आवश्यकता नहीं है क्योंकि यह पहले से ही "पहले से शामिल" है।
विचार करें कि क्या आपको इसकी आवश्यकता है - उर्फ "पूरी तरह से" असामान्य करें
तो ऐसे मामलों में जहां आप बहुत अधिक जानते हैं कि आप वास्तव में इस तरह के सरणी में अधिकांश डेटा से निपटने में रूचि नहीं रखते हैं, आम तौर पर इसे केवल एक संग्रह में केवल एक और संपत्ति के साथ एक संग्रह में रखना अधिक समझ में आता है "माता-पिता" की पहचान करने के लिए ऐसे "जुड़ने" की आवश्यकता कभी-कभी होनी चाहिए:
{
"_id": 1,
"parent_id": 1,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"_id": 2,
"parent_id": 1,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-01"),
"quantity": 1
},
{
"_id": 3,
"parent_id": 1,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-02"),
"quantity": 1
},
{
"_id": 4,
"parent_id": 1,
"first_item": "A",
"second_item": "A",
"third_item": "B",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"_id": 5,
"parent_id": 1,
"first_item": "A",
"second_item": "A",
"third_item": "B",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"_id": 6,
"parent_id": 1,
"first_item": "A",
"second_item": "B",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"_id": 7,
"parent_id": 2,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 2,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"_id": 8,
"parent_id": 2,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-10-31"),
"quantity": 1
},
{
"_id": 9,
"parent_id": 2,
"first_item": "A",
"second_item": "A",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
},
{
"_id": 10,
"parent_id": 3,
"first_item": "A",
"second_item": "B",
"third_item": "A",
"price": 1,
"sales_date": new Date("2018-11-03"),
"quantity": 1
}
फिर से यह वही डेटा है, लेकिन इस बार माता-पिता के संदर्भ में पूरी तरह से अलग दस्तावेजों में सबसे अच्छा मामले में जहां आपको वास्तव में किसी अन्य उद्देश्य के लिए इसकी आवश्यकता हो सकती है। ध्यान दें कि यहां सभी एकत्रीकरण मूल डेटा से बिल्कुल भी संबंधित नहीं हैं और यह भी स्पष्ट है कि अतिरिक्त प्रदर्शन और हटाई गई जटिलता केवल एक अलग संग्रह में संग्रहीत करके कहां आती है:
db.collection.aggregate([
{ "$match": {
"first_item": "A",
"second_item": "A",
"third_item": "A",
"sales_date": {
"$gte": new Date("2018-11-01"),
"$lt": new Date("2018-12-01")
}
}},
{ "$group": {
"_id": {
"date": "$sales_date",
"price": "$price"
},
"quantity_sold": { "$avg": "$quantity" }
}},
{ "$group": {
"_id": "$_id.date",
"prices": {
"$push": {
"price": "$_id.price",
"quantity_sold": "$quantity_sold"
}
},
"quantity_sold": { "$avg": "$quantity_sold" }
}}
])
चूंकि सब कुछ पहले से ही एक दस्तावेज़ है, इसलिए "फ़िल्टर डाउन एरेज़" . की कोई आवश्यकता नहीं है या कोई अन्य जटिलता है। आप केवल मिलान करने वाले दस्तावेज़ों का चयन कर रहे हैं और परिणामों को एकत्रित कर रहे हैं, ठीक उसी दो अंतिम चरणों के साथ जो हमेशा मौजूद रहे हैं।
केवल अंतिम परिणाम प्राप्त करने के उद्देश्य से, यह उपरोक्त विकल्पों में से किसी एक से कहीं बेहतर प्रदर्शन करता है। प्रश्न में प्रश्न वास्तव में केवल "विवरण" डेटा से संबंधित है, इसलिए कार्रवाई का सबसे अच्छा तरीका माता-पिता से विवरण को पूरी तरह से अलग करना है क्योंकि यह हमेशा सर्वोत्तम प्रदर्शन लाभ प्रदान करने वाला है।
और यहां समग्र बिंदु वह है जहां शेष एप्लिकेशन का वास्तविक एक्सेस पैटर्न कभी नहीं संपूर्ण सरणी सामग्री को वापस करने की आवश्यकता है, तो शायद इसे वैसे भी एम्बेड नहीं किया जाना चाहिए था। प्रतीत होता है कि अधिकांश "लिखने" कार्यों को वैसे भी संबंधित माता-पिता को छूने की आवश्यकता नहीं होनी चाहिए, और यह एक और निर्णायक कारक है जहां यह काम करता है या नहीं।
निष्कर्ष
सामान्य संदेश फिर से है कि एक सामान्य नियम के रूप में आपको कभी भी सरणियों को घोंसला नहीं बनाना चाहिए। अधिक से अधिक आपको संबंधित मूल दस्तावेज़ के भीतर आंशिक रूप से विकृत डेटा के साथ एक "एकवचन" सरणी रखनी चाहिए, और जहां शेष पहुंच पैटर्न वास्तव में माता-पिता और बच्चे का उपयोग बिल्कुल भी नहीं करते हैं, तो डेटा को वास्तव में अलग किया जाना चाहिए।पी>
"बड़ा" परिवर्तन यह है कि डेटा को सामान्य बनाने के सभी कारण वास्तव में अच्छे हैं, ऐसे एम्बेडेड दस्तावेज़ सिस्टम के दुश्मन बन जाते हैं। "जुड़ने" से बचना हमेशा अच्छा होता है, लेकिन "जुड़" डेटा की उपस्थिति के लिए जटिल नेस्टेड संरचना बनाना वास्तव में आपके लाभ के लिए कभी भी कारगर नहीं होता है।
जो आप "सोचते हैं" से निपटने की लागत सामान्यीकरण है, आमतौर पर आपके अंतिम भंडारण के भीतर डुप्लिकेट और असामान्य डेटा के अतिरिक्त भंडारण और रखरखाव को समाप्त कर देता है।
यह भी ध्यान दें कि उपरोक्त सभी फॉर्म एक ही परिणाम सेट लौटाते हैं। यह बहुत ही व्युत्पन्न है कि संक्षिप्तता के लिए नमूना डेटा में केवल एकवचन आइटम शामिल हैं, या अधिक से अधिक जहां कई मूल्य बिंदु हैं, "औसत" अभी भी 1
है चूंकि वैसे भी सभी मूल्य यही हैं। लेकिन इसे समझाने की सामग्री पहले से ही बहुत लंबी है इसलिए यह वास्तव में "उदाहरण के लिए" है:
{
"_id" : ISODate("2018-11-01T00:00:00Z"),
"prices" : [
{
"price" : 1,
"quantity_sold" : 1
}
],
"quantity_sold" : 1
}
{
"_id" : ISODate("2018-11-02T00:00:00Z"),
"prices" : [
{
"price" : 1,
"quantity_sold" : 1
}
],
"quantity_sold" : 1
}
{
"_id" : ISODate("2018-11-03T00:00:00Z"),
"prices" : [
{
"price" : 1,
"quantity_sold" : 1
},
{
"price" : 2,
"quantity_sold" : 1
}
],
"quantity_sold" : 1
}