आप $pull
. कर सकते हैं "बाहरी सरणी" से "पहला मैच" केवल "सभी आंतरिक तत्वों" को हटाकर:
db.Events.updateMany(
{
"Distributions.DistributionData": {
"$elemMatch": {
"Key": null,
"Value": null,
"Children": null
}
}
},
{
"$pull": {
"Distributions.$.DistributionData": {
"Key": null,
"Value": null,
"Children": null
}
}
}
)
यह ठीक है अगर आपके पास "Distributions"
. में केवल एक प्रविष्टि है सरणी या उन प्रविष्टियों में से कम से कम केवल एक में बाल सरणी प्रविष्टियाँ हैं जो स्थिति से मेल खाती हैं। इस प्रकार स्थितीय $
ऑपरेटर MongoDB के सभी संस्करणों के साथ काम करता है।
यदि डेटा में "बाहरी" "Distributions"
. में "एकाधिक" मिलान होंगे सरणी तो अगर आपके पास MongoDB 3.6 है तो आप स्थितीय फ़िल्टर्ड $[<identifier>]
लागू कर सकते हैं सभी मिलान वाली प्रविष्टियों को संशोधित करने के लिए ऑपरेटर:
db.Events.updateMany(
{
"Distributions.DistributionData": {
"$elemMatch": {
"Key": null,
"Value": null,
"Children": null
}
}
},
{
"$pull": {
"Distributions.$[element].DistributionData": {
"Key": null,
"Value": null,
"Children": null
}
}
},
{
"arrayFilters": [
{ "element.DistributionData": {
"$elemMatch": {
"Key": null,
"Value": null,
"Children": null
}
}}
]
}
)
उस स्थिति में arrayFilters
विकल्प एक शर्त को परिभाषित करता है जिसके द्वारा हम "बाहरी" सरणी में प्रविष्टियों का मिलान करते हैं ताकि यह वास्तव में हर उस चीज़ पर लागू हो सके जो मेल खाती है।
या वास्तव में $pull
. के बाद से अनिवार्य रूप से वे स्थितियां ही हैं, तो आप वैकल्पिक रूप से केवल स्थितीय सभी $[]
. का उपयोग कर सकते हैं इस मामले में ऑपरेटर:
db.Event.updateMany(
{
"Distributions.DistributionData": {
"$elemMatch": {
"Key": null,
"Value": null,
"Children": null
}
}
},
{
"$pull": {
"Distributions.$[].DistributionData": {
"Key": null,
"Value": null,
"Children": null
}
}
}
)
किसी भी मामले में सभी null
. के साथ आंतरिक आइटम को हटाकर प्रश्न में दस्तावेज़ को बदल देता है कुंजियाँ:
{
"_id" : UUID("cf397865-c000-4f51-8959-1aae84769706"),
"CreationDateTime" : ISODate("2016-05-06T05:09:14.589Z"),
"WKT" : "",
"Distributions" : [
{
"_id" : UUID("bb95bedb-4baa-4ada-90b1-0d763e70ebfe"),
"DeliveryType" : 1,
"DistributionData" : [
{
"Key" : "Topic",
"Value" : "Topics",
"Children" : null
},
{
"Key" : "Message",
"Value" : "test",
"Children" : null
}
],
"Schedules" : [
ISODate("2016-05-06T05:09:56.988Z")
]
}
]
}
"क्वेरी" शर्तें सभी $elemMatch
. का उपयोग करती हैं दस्तावेज़ चयन के लिए। यह वास्तव में स्थितीय $
. के लिए आवश्यक है ऑपरेटर "पहले मैच" के लिए उपयोग की जाने वाली "स्थिति सूचकांक" प्राप्त करने के लिए। हालांकि यह वास्तव में स्थितीय फ़िल्टर किए गए $[<identifier>]
के लिए "आवश्यकता" नहीं है। या स्थितीय सभी $[]
ऑपरेटर, यह अभी भी उपयोगी है इसलिए आप अद्यतन के लिए दस्तावेज़ों पर भी विचार नहीं करते हैं जो $pull
की बाद की अद्यतन शर्तों से मेल नहीं खाएंगे या arrayFilters
विकल्प।
जहां तक $pull
. का सवाल है स्वयं, यहाँ की शर्तें वास्तव में "प्रत्येक" सरणी तत्व पर लागू होती हैं, इसलिए $elemMatch
की कोई आवश्यकता नहीं है उस ऑपरेशन में चूंकि हम पहले से ही "तत्व" स्तर को देख रहे हैं।
तीसरा उदाहरण दर्शाता है कि स्थितीय सभी $[]
ऑपरेटर बस उन $pull
. का उपयोग कर सकता है प्रत्येक "आंतरिक" सरणी तत्व के विचार में शर्तें और केवल सभी "बाहरी" सरणी तत्वों पर लागू होंगी। तो स्थितीय फ़िल्टर का वास्तविक बिंदु $[<identifier>]
अभिव्यक्ति "केवल" उन "बाहरी" सरणी तत्वों को संसाधित करना है जो वास्तव में "आंतरिक" स्थिति से मेल खाते हैं। इसलिए हम $elemMatch
का उपयोग क्यों करते हैं? प्रत्येक "आंतरिक" सरणी तत्व से मेल खाने के विचार में।
यदि आपके पास वास्तव में कम से कम MongoDB 3.6 नहीं है, तो आप पहले फॉर्म का उपयोग कर रहे हैं और संभावित रूप से इसे दोहरा रहे हैं जब तक कि अपडेट अंततः कोई और संशोधित दस्तावेज़ नहीं लौटाते हैं जो यह दर्शाता है कि स्थिति से मेल खाने वाले कोई और तत्व नहीं बचे हैं।
मोंगोडब में एकाधिक ऐरे तत्वों को अपडेट करने के दृष्टिकोण के रूप में "विकल्प" पर अधिक विस्तृत लेखन है, लेकिन जब तक आपका डेटा या तो प्रारंभिक मामले के अनुरूप है या आपके पास वास्तव में मोंगोडीबी 3.6 उपलब्ध है, तो यह सही है यहां पहुंचें।
यदि आप MongoDB 3.6 के लिए नए सिंटैक्स का पूरा प्रभाव देखना चाहते हैं। यह उस प्रश्न के दस्तावेज़ में परिवर्तन है जिसका उपयोग मैंने यहाँ अद्यतन विवरणों को सत्यापित करने के लिए किया था:
{
"_id" : UUID("cf397865-c000-4f51-8959-1aae84769706"),
"CreationDateTime" : ISODate("2016-05-06T05:09:14.589Z"),
"WKT" : "",
"Distributions" : [
{
"_id" : UUID("bb95bedb-4baa-4ada-90b1-0d763e70ebfe"),
"DeliveryType" : 1,
"DistributionData" : [
{
"Key" : "Topic",
"Value" : "Topics",
"Children" : null
},
{
"Key" : null,
"Value" : null,
"Children" : null
},
{
"Key" : "Message",
"Value" : "test",
"Children" : null
},
{
"Key" : null,
"Value" : null,
"Children" : null
}
],
"Schedules" : [
ISODate("2016-05-06T05:09:56.988Z")
]
},
{
"_id" : UUID("bb95bedb-4baa-4ada-90b1-0d763e70ebfe"),
"DeliveryType" : 1,
"DistributionData" : [
{
"Key" : "Topic",
"Value" : "Topics",
"Children" : null
},
{
"Key" : null,
"Value" : null,
"Children" : null
},
{
"Key" : "Message",
"Value" : "test",
"Children" : null
},
{
"Key" : null,
"Value" : null,
"Children" : null
}
],
"Schedules" : [
ISODate("2016-05-06T05:09:56.988Z")
]
}
]
}
जो मूल रूप से कुछ प्रविष्टियों को "बाहरी" और "आंतरिक" दोनों को डुप्लिकेट करता है यह दिखाने के लिए कि कथन सभी null
को कैसे हटाता है मान।
नोट arrayFilters
.update()
. के लिए "विकल्प" तर्क में निर्दिष्ट हैं और विधियों की तरह, सिंटैक्स आम तौर पर सभी हाल के रिलीज़ ड्राइवर संस्करणों और यहां तक कि MongoDB 3.6 के रिलीज़ से पहले के संस्करणों के साथ संगत है।
हालांकि यह mongo
. के बारे में सच नहीं है खोल, जिस तरह से वहां विधि लागू की गई है ("विडंबना यह है कि पिछड़े संगतता के लिए") arrayFilters
तर्क को एक आंतरिक विधि द्वारा पहचाना और हटाया नहीं जाता है जो पिछले MongoDB सर्वर संस्करणों और "विरासत" .update()
के साथ "पिछड़ा संगतता" देने के लिए विकल्पों को पार्स करता है। एपीआई कॉल सिंटैक्स।
इसलिए यदि आप mongo
. में कमांड का उपयोग करना चाहते हैं शेल या अन्य "खोल आधारित" उत्पाद (विशेष रूप से रोबो 3T) आपको विकास शाखा से नवीनतम संस्करण या 3.6 या उससे अधिक के रूप में उत्पादन रिलीज की आवश्यकता है।
रोबो 3T विशेष रूप से यहाँ अभी भी एक MongoDB 3.4 शेल पर आधारित है। तो एक सक्षम MongoDB 3.6 उदाहरण से कनेक्ट होने पर भी, ये विकल्प इस प्रोग्राम से सर्वर को पास नहीं किए जाएंगे। केवल शेल और समर्थित उत्पादों के साथ रहने की सलाह दी जाती है, हालांकि कुछ अन्य पेशकशें हैं जिनकी समान सीमा नहीं है।