वास्तव में ऐसा करना जो ऐसा लगता है जैसे आप कहते हैं कि आप कर रहे हैं, एक विलक्षण ऑपरेशन नहीं है, लेकिन मैं इसे करने के लिए या अन्य संभावित स्थितियों को कवर करने के लिए आवश्यक भागों के माध्यम से चलूंगा।
आप जो खोज रहे हैं वह आंशिक रूप से स्थितीय $
. है ऑपरेटर। आपको अपनी इच्छित सरणी के तत्व को "ढूंढने" के लिए अपनी क्वेरी के हिस्से की भी आवश्यकता है।
db.products.update(
{
"_id": ObjectId("536c55bf9c8fb24c21000095"),
"recentviews.viewedby": "abc"
},
{
"$set": {
"recentviews.$.vieweddate": ISODate("2014-05-09T04:12:47.907Z")
}
}
)
तो $
सरणी में मिलान की स्थिति के लिए खड़ा है, इसलिए अद्यतन भाग जानता है कि सरणी में कौन सा आइटम अपडेट करना है। आप सरणी में दस्तावेज़ के अलग-अलग क्षेत्रों तक पहुँच सकते हैं या उस स्थिति में अद्यतन करने के लिए पूरे दस्तावेज़ को निर्दिष्ट कर सकते हैं।
db.products.update(
{
"_id": ObjectId("536c55bf9c8fb24c21000095"),
"recentviews.viewedby": "abc"
},
{
"$set": {
"recentviews.$": {
"viewedby": "abc",
"vieweddate": ISODate("2014-05-09T04:12:47.907Z")
}
}
)
यदि फ़ील्ड वास्तव में नहीं बदलते हैं और आप केवल एक नया सरणी तत्व सम्मिलित करना चाहते हैं यदि ठीक वही मौजूद नहीं है, तो आप $addToSet
का उपयोग कर सकते हैं
db.products.update(
{
"_id": ObjectId("536c55bf9c8fb24c21000095"),
"recentviews.viewedby": "abc"
},
{
$addToSet:{
"recentviews": {
"viewedby": "abc",
"vieweddate": ISODate("2014-05-09T04:12:47.907Z")
}
}
)
हालाँकि, यदि आप केवल एक एकल कुंजी मान द्वारा किसी सरणी को "पुश" करने की तलाश कर रहे हैं, यदि वह मौजूद नहीं है, तो आपको कुछ और मैन्युअल हैंडलिंग करने की आवश्यकता है, पहले यह देखकर कि क्या सरणी में तत्व मौजूद है और फिर बना रहा है <मजबूत>$push
बयान जहां यह नहीं है।
अद्यतन से प्रभावित दस्तावेज़ों की संख्या को ट्रैक करके ऐसा करने में आपको नेवले के तरीकों से कुछ मदद मिलती है:
Product.update(
{
"_id": ObjectId("536c55bf9c8fb24c21000095"),
"recentviews.viewedby": "abc"
},
{
"$set": {
"recentviews.$": {
"viewedby": "abc",
"vieweddate": ISODate("2014-05-09T04:12:47.907Z")
}
},
function(err,numAffected) {
if (numAffected == 0) {
// Document not updated so you can push onto the array
Product.update(
{
"_id": ObjectId("536c55bf9c8fb24c21000095")
},
{
"$push": {
"recentviews": {
"viewedby": "abc",
"vieweddate": ISODate("2014-05-09T04:12:47.907Z")
}
}
},
function(err,numAffected) {
}
);
}
}
);
यहाँ सावधानी का एकमात्र शब्द यह है कि MongoDB 2.6 से पुराने संस्करणों में राइट-कॉन्सर संदेशों में थोड़ा सा कार्यान्वयन परिवर्तन है। अभी इस बारे में अनिश्चित होना कि कैसे नेवला एपीआई वास्तव में numAffected
की वापसी को लागू करता है कॉलबैक में तर्क अंतर का कुछ मतलब हो सकता है।
पिछले संस्करणों में, भले ही आपके द्वारा प्रारंभिक अपडेट में भेजा गया डेटा किसी मौजूदा तत्व से सटीक रूप से मेल खाता हो और कोई वास्तविक परिवर्तन आवश्यक नहीं था, फिर भी "संशोधित" राशि 1
के रूप में वापस कर दी जाएगी। हालांकि वास्तव में कुछ भी अपडेट नहीं किया गया था।
MongoDB 2.6 से लेखन चिंता प्रतिक्रिया में दो भाग होते हैं। एक हिस्सा संशोधित दस्तावेज़ दिखाता है और दूसरा मैच दिखाता है। इसलिए जब मैच किसी मौजूदा तत्व से मेल खाने वाले क्वेरी भाग द्वारा वापस किया जाएगा, वास्तविक संशोधित दस्तावेज़ गणना 0
के रूप में वापस आ जाएगी यदि वास्तव में कोई परिवर्तन आवश्यक नहीं था।
तो इस पर निर्भर करते हुए कि नेवले में वास्तव में रिटर्न नंबर कैसे लागू किया जाता है, यह वास्तव में $addToSet
का उपयोग करने के लिए सुरक्षित हो सकता है उस आंतरिक अद्यतन पर ऑपरेटर यह सुनिश्चित करने के लिए कि यदि शून्य प्रभावित दस्तावेज़ों का कारण केवल यह नहीं था कि सटीक तत्व पहले से मौजूद था।