नहीं, वास्तव में इसका कोई बेहतर समाधान नहीं है, इसलिए शायद स्पष्टीकरण के साथ।
मान लीजिए कि आपके पास एक दस्तावेज़ है जिसकी संरचना आपके द्वारा दर्शाई गई है:
{
"name": "foo",
"bars": [{
"name": "qux",
"somefield": 1
}]
}
अगर आप ऐसा अपडेट करते हैं
db.foo.update(
{ "name": "foo", "bars.name": "qux" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
तब सब ठीक है क्योंकि मेल खाने वाला दस्तावेज़ मिल गया था। लेकिन अगर आप "bars.name" का मान बदलते हैं:
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } },
{ "upsert": true }
)
तब आपको असफलता हाथ लगेगी। केवल एक चीज जो वास्तव में यहां बदल गई है, वह यह है कि MongoDB 2.6 और इसके बाद के संस्करण में त्रुटि थोड़ी अधिक संक्षिप्त है:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16836,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: bars.$.somefield"
}
})
यह कुछ मायनों में बेहतर है, लेकिन आप वास्तव में वैसे भी "अपरर्ट" नहीं करना चाहते हैं। आप जो करना चाहते हैं वह तत्व को उस सरणी में जोड़ना है जहां "नाम" वर्तमान में मौजूद नहीं है।
तो आप वास्तव में जो चाहते हैं वह "अप्सर्ट" ध्वज के बिना अद्यतन प्रयास से "परिणाम" है यह देखने के लिए कि कोई दस्तावेज़ प्रभावित हुआ है या नहीं:
db.foo.update(
{ "name": "foo", "bars.name": "xyz" },
{ "$set": { "bars.$.somefield": 2 } }
)
प्रतिक्रिया में उपज:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
इसलिए जब संशोधित दस्तावेज़ 0
हों तो आप जानते हैं कि आप निम्नलिखित अपडेट जारी करना चाहते हैं:
db.foo.update(
{ "name": "foo" },
{ "$push": { "bars": {
"name": "xyz",
"somefield": 2
}}
)
वास्तव में आप जो चाहते हैं उसे करने का कोई दूसरा तरीका नहीं है। चूंकि सरणी में परिवर्धन सख्ती से "सेट" प्रकार का ऑपरेशन नहीं है, आप $addToSet
का उपयोग नहीं कर सकते हैं वहां "बल्क अपडेट" कार्यक्षमता के साथ संयुक्त, ताकि आप अपने अपडेट अनुरोधों को "कैस्केड" कर सकें।
इस मामले में ऐसा लगता है कि आपको परिणाम की जांच करने की आवश्यकता है, या अन्यथा पूरे दस्तावेज़ को पढ़ना स्वीकार करें और जांच करें कि कोड में एक नया सरणी तत्व अपडेट या सम्मिलित करना है या नहीं।