अगर मैं अनिवार्य रूप से आपका सार प्राप्त करता हूं तो आप मूल रूप से चाहते हैं
- वह आइटम खींचें जो आपके संदर्भ सरणी से आवश्यक नहीं है
- अपने मुख्य-संदर्भ फ़ील्ड का मान परिवर्तित सरणी के पहले तत्व पर सेट करें
और दस्तावेज़ों को तार-तार किए बिना एक ही अपडेट में पूरा करें।
लेकिन दुख की बात है कि ऐसा नहीं किया जा सकता। इसके साथ मुख्य समस्या यह है कि अद्यतन किए जा रहे दस्तावेज़ के भीतर किसी अन्य फ़ील्ड के मान को संदर्भित करने का कोई तरीका नहीं है। फिर भी, बिना पुनरावृति के ऐसा करने के लिए आपको परिवर्तित . तक पहुंच की भी आवश्यकता होगी नया पहला तत्व प्राप्त करने के लिए सरणी।
शायद एक तरीका यह है कि आप जो चाहते हैं उसे पूरा करने के लिए अपनी स्कीमा पर फिर से विचार करें। यहां मेरा विकल्प आपके संदर्भ दस्तावेज़ों पर थोड़ा विस्तार करेगा और मुख्य-संदर्भ फ़ील्ड की आवश्यकता को हटा देगा।
ऐसा लगता है कि आप जिस धारणा के साथ अपडेट पर रहने के इच्छुक हैं, वह यह है कि यदि हटाया गया संदर्भ मुख्य-संदर्भ था तो आप सरणी में पहले तत्व के लिए नया मुख्य-संदर्भ सेट कर सकते हैं। इसे ध्यान में रखते हुए निम्नलिखित संरचना पर विचार करें:
refs: [ { oid: "object1" }, { oid: "object2" }, { oid: "object5", main: true } ]
इन्हें oid
. वाले दस्तावेज़ों में बदलकर संपत्ति जिसे ऑब्जेक्ट आईडी पर सेट किया जाएगा, यह दस्तावेज़ पर एक अतिरिक्त संपत्ति रखने का विकल्प देता है जो निर्दिष्ट करता है कि कौन सा डिफ़ॉल्ट है। यह आसानी से निर्धारित किया जा सकता है कि कौन सी आईडी मुख्य संदर्भ है।
अब यह भी विचार करें कि क्या होगा यदि ओड फ़ील्ड में "ऑब्जेक्ट 5" से मेल खाने वाले दस्तावेज़ को सरणी से खींचा गया था:
refs: [ { oid: "object1" }, { oid: "object2" } ]
तो जब आप क्वेरी करते हैं जिसके लिए main-reference
. है पहले के तर्क के अनुसार आप सरणी में पहला दस्तावेज़ स्वीकार करते हैं। अब निश्चित रूप से, आपकी आवेदन आवश्यकताओं के लिए, यदि आप एक अलग main-reference
. सेट करना चाहते हैं आप बस दस्तावेज़ को बदल दें
refs: [ { oid: "object1" }, { oid: "object2", main: true } ]
और अब तर्क सरणी तत्व को चुनने के लिए बना हुआ है जिसमें मुख्य गुण सत्य के रूप में वरीयता में होगा, और जैसा कि ऊपर दिखाया गया है कि यदि वह संपत्ति किसी भी तत्व दस्तावेज़ पर मौजूद नहीं है तो पहले तत्व पर वापस आएं।
उस सब के साथ, सभी दस्तावेजों में उस सरणी से किसी ऑब्जेक्ट के सभी संदर्भों को खींचने के लिए आपका ऑपरेशन काफी सरल हो जाता है, जैसा कि शेल में किया जाता है (उसी प्रारूप को मूल रूप से जो भी ड्राइवर पर लागू होना चाहिए):
db.books.update(
{ "refs.oid": "object5" },
{ $pull: { refs: {oid: "object5"} } }, false, true )
क्वेरी और अपडेट ऑपरेशन के लिए दो अतिरिक्त तर्क upsert
. हैं और multi
क्रमश। इस मामले में, upsert
अधिक अर्थ नहीं है क्योंकि हम केवल मौजूद दस्तावेज़ों को संशोधित करना चाहते हैं, और multi
इसका मतलब है कि हम मेल खाने वाली हर चीज को अपडेट करना चाहते हैं। डिफ़ॉल्ट केवल पहले दस्तावेज़ को बदलना है।
स्वाभाविक रूप से मैंने सभी नोटेशन को छोटा कर दिया है लेकिन निश्चित रूप से मान आपके इरादे के अनुसार वास्तविक ऑब्जेक्ट आईडी हो सकते हैं। यह मान लेना भी उचित प्रतीत होता है कि main-reference
. का आपका मुख्य उपयोग एक बार जब आप दस्तावेज़ को पुनः प्राप्त कर लेते हैं। एक क्वेरी को परिभाषित करना जो main-reference
लौटाती है उल्लिखित तर्क का पालन करके संभव होना चाहिए, लेकिन जैसा कि यह खड़ा है मैंने यहां बहुत कुछ टाइप किया है और रात के खाने के लिए ब्रेक की जरूरत है :)
मुझे लगता है कि आप जो हासिल करना चाहते हैं उसके लिए वायर पुनरावृत्तियों से बचने के लिए आपकी स्कीमा पर फिर से विचार करने के लिए यह एक सार्थक मामला प्रस्तुत करता है।