2017 अपडेट
$lookup अब सीधे स्थानीय फ़ील्ड के रूप में एक सरणी का उपयोग कर सकता है। $unwind
अब इसकी आवश्यकता नहीं है।
पुराना उत्तर
$lookup
एकत्रीकरण पाइपलाइन चरण सीधे एक सरणी के साथ काम नहीं करेगा। डिज़ाइन का मुख्य उद्देश्य संभावित संबंधित डेटा पर "एक से कई" प्रकार के जुड़ने (या वास्तव में एक "लुकअप") के रूप में "बाएं शामिल" के लिए है। लेकिन मान एकवचन होने के लिए अभिप्रेत है न कि एक सरणी।
इसलिए आपको $lookup
. करने से पहले सामग्री को "डी-नॉर्मलाइज" करना होगा इसके लिए काम करने के लिए ऑपरेशन। और इसका अर्थ है $unwind
. का उपयोग करना :
db.orders.aggregate([
// Unwind the source
{ "$unwind": "$products" },
// Do the lookup matching
{ "$lookup": {
"from": "products",
"localField": "products",
"foreignField": "_id",
"as": "productObjects"
}},
// Unwind the result arrays ( likely one or none )
{ "$unwind": "$productObjects" },
// Group back to arrays
{ "$group": {
"_id": "$_id",
"products": { "$push": "$products" },
"productObjects": { "$push": "$productObjects" }
}}
])
$lookup
. के बाद प्रत्येक सरणी सदस्य से मेल खाता है परिणाम स्वयं एक सरणी है, इसलिए आप $unwind
फिर से और $group
करने के लिए $push
अंतिम परिणाम के लिए नई सरणियाँ।
ध्यान दें कि कोई भी "लेफ्ट जॉइन" मैच जो नहीं मिला है, दिए गए उत्पाद पर "productObjects" के लिए एक खाली सरणी बनाएगा और इस प्रकार "उत्पाद" तत्व के लिए दस्तावेज़ को नकार देगा जब दूसरा $unwind
कहा जाता है।
हालांकि एक सरणी के लिए एक सीधा आवेदन अच्छा होगा, यह वर्तमान में एक एकल मूल्य को कई संभावित लोगों से मेल करके काम करता है।
$lookup
. के रूप में मूल रूप से बहुत नया है, यह वर्तमान में काम करता है जो उन लोगों के लिए परिचित होगा जो नेवले से .populate()
के "गरीब आदमी संस्करण" के रूप में परिचित होंगे। वहाँ की पेशकश की विधि। अंतर यह है कि $lookup
क्लाइंट के विपरीत "जॉइन" की "सर्वर साइड" प्रोसेसिंग और $lookup
में कुछ "परिपक्वता" की पेशकश करता है वर्तमान में क्या कमी है .populate()
ऑफ़र (जैसे किसी सरणी पर सीधे लुकअप को प्रक्षेपित करना)।
यह वास्तव में SERVER-22881 में सुधार के लिए एक नियत मुद्दा है, इसलिए कुछ भाग्य के साथ यह अगली रिलीज़ या उसके तुरंत बाद हिट हो जाएगा।
एक डिजाइन सिद्धांत के रूप में, आपकी वर्तमान संरचना न तो अच्छी है और न ही खराब है, लेकिन किसी भी "जुड़ने" को बनाते समय केवल ओवरहेड्स के अधीन है। जैसे, शुरुआत में MongoDB का मूल स्थायी सिद्धांत लागू होता है, जहां यदि आप एक संग्रह में "पूर्व-जुड़े" डेटा के साथ "रह सकते हैं", तो ऐसा करना सबसे अच्छा है।
एक और बात जो $lookup
. के बारे में कही जा सकती है एक सामान्य सिद्धांत के रूप में, यह है कि यहां "शामिल होने" का इरादा यहां दिखाए गए तरीके से दूसरी तरफ काम करना है। इसलिए अन्य दस्तावेज़ों के "संबंधित आईडी" को "पैरेंट" दस्तावेज़ में रखने के बजाय, सामान्य सिद्धांत जो सबसे अच्छा काम करता है, वह है जहाँ "संबंधित दस्तावेज़ों" में "पैरेंट" का संदर्भ होता है।
तो $lookup
एक "रिलेशनशिप डिज़ाइन" के साथ "सर्वश्रेष्ठ काम" करने के लिए कहा जा सकता है जो कि नेवला जैसे कुछ के विपरीत है .populate()
यह क्लाइंट साइड जॉइन करता है। इसके बजाय प्रत्येक "कई" के भीतर "एक" की पहचान करके, फिर आप $unwind
की आवश्यकता के बिना संबंधित वस्तुओं को खींच लेते हैं पहले सरणी।