افزایش و کاهش مقادیر و اپراتورهای مربوطه

Increasing and Decreasing Values

20 اردیبهشت 1401
درسنامه درس 42 از سری دوره جامع آموزش MongoDB
MongoDB: افزایش و کاهش مقادیر و اپراتور های مربوطه (قسمت 44)

ما در قسمت قبل در رابطه با دستورات updateOne و updateMany صحبت کرده بودیم. در این قسمت می خواهم در مورد افزایش و کاهش مقدار عددی یک فیلد صحبت کنم. به طور مثال کاربر Nastaran در پایگاه داده ما 30 سال دارد و فرض ما برای این جسله این است که Nastaran یک سال بزرگ تر شده است و حالا باید 31 ساله شود. در حالت عادی می توانیم از updateOne یا updateMany استفاده کرده و اپراتور set$ را به کار بگیریم تا 30 را به 31 تبدیل کنیم. مسئله اینجاست که در برنامه های واقعی، ما سن کاربران خود را نمی دانیم و هر سال که رد بشود باید یک واحد به آن اضافه کنیم. این یک واحد ممکن است به 30 سال یا 50 سال یا 10 سال اضافه شود بنابراین استفاده از اپراتور set$ ممکن نیست. مثلا اگر 1000 کاربر را در پایگاه داده خود داشته باشیم، چطور می توانیم یک سال به سن هر کدام از آن ها اضافه کنیم؟

اضافه کردن یک یا چند واحد به عددی خاص، آنقدر عملیات رایجی محسوب می شود که MongoDB یک اپراتور خاص برایش دارد. بنابراین می توانیم کاربر Nastaran را پیدا کرده و بگوییم:

db.users.updateOne({name: "Nastaran"}, {$inc: {age: 1}})

من با دستور بالا ابتدا اولین کاربری که نام Nastaran را داشته باشد (به دلیل اینکه updateOne اولین نتیجه را پیدا می کند) پیدا کرده و با اپراتور inc$ (مخفف increment - به معنی افزایش) 1 واحد به خصوصیت age اضافه کرده ام. نتیجه اجرای کوئری بالا طبق انتظار ما است:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

حالا کاربر ما 31 سال دارد. البته با اینکه این اپراتور inc$ نام دارد که مخفف increment است اما می توانید با آن decrement (کاهش) نیز انجام دهید. مثلا سن Nastaran را دوباره کم کرده و به 30 برمی گردانم:

db.users.updateOne({name: "Nastaran"}, {$inc: {age: -1}})

تنها کاری که کرده ام اضافه کردن علامت منفی می باشد. البته یادتان باشد که می توانیم کوئری های خود را پیچیده تر کنیم و به جای اینکه فقط یک مقدار را کاهش یا افزایش بدهیم، مقادیر دیگری را نیز تغییر دهیم. مثلا:

db.users.updateOne({name: "Nastaran"}, {$inc: {age: 1}, $set: {isSporty: false}})

یعنی علاوه بر اضافه کردن به سن Nastaran، خصوصیت isSporty را نیز برایش روی False گذاشته ایم. البته او این خصوصیت را ندارد بنابراین برایش ساخته خواهد شد. برای مشاهده نتیجه می توانیم به شکل زیر عمل کنیم:

db.users.find({name: "Nastaran"}).pretty()

نتیجه این کوئری، به شکل زیر نمایش داده می شود:

"_id" : ObjectId("5eb295a448ff1d422538a356"),
 "name" : "Nastaran",                         
 "hobbies" : [                                
         {                                    
                 "title" : "Reading",         
                 "frequency" : 5              
         },                                   
         {                                    
                 "title" : "Movies",          
                 "frequency" : 7              
         }                                    
 ],                                           
 "phone" : "352380532895",                    
 "age" : 31,                                  
 "isSporty" : false                           

ما اپراتور های مختلفی را نیز برای کار با این نوع از عملیات ها خواهیم داشت. مثلا فرض کنید که قصد ما تنظیم سن Pooya روی 20 است اما فقط به شرطی که سن فعلی او بیشتر از 20 باشد. در حال حاضر سن Pooya در پایگاه داده ما 25 است. برای انجام این کار باید بگوییم:

db.users.updateOne({name: "Pooya"}, {$min: {age: 20}})

با اجرای این کوئری، نتیجه زیر را می بینیم:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

از آنجایی که سن Pooya 25 بود شرط ما (بیشتر بودن از 20) بر قرار است بنابراین حالا سن پویا باید 20 باشد. ما می توانیم این موضوع را از طریق کوئری زیر بررسی کنیم:

db.users.find({name: "Pooya"}).pretty()

نتیجه این کوئری به شکل زیر است:

"_id" : ObjectId("5eb3c250c91228985d228864"), 
 "name" : "Pooya",                             
 "hobbies" : [                                 
         {                                     
                 "title" : "Sports",           
                 "frequency" : 5               
         },                                    
         {                                     
                 "title" : "Cooking",          
                 "frequency" : 3               
         },                                    
         {                                     
                 "title" : "Hiking",           
                 "frequency" : 1               
         }                                     
 ],                                            
 "age" : 20,                                   
 "phone" : 75834965320948                      

بنابراین سن Pooya با موفقیت به 20 تغییر کرده است. سوال من این است که اگر شرط ما برقرار نباشد چه می شود؟ مثلا Pooya در حال حاضر 20 سال دارد اما اگر کوئری ما بگوید حداقل 25 سال، چه اتفاقی می افتد؟

db.users.updateOne({name: "Pooya"}, {$min: {age: 25}})

این کوئری می گوید اگر Pooya حداقل 25 سال داشت (25 و بالاتر) سن او را به 25 سال تغییر بده اما سن Pooya در حال حاضر روی 20 است بنابراین هیچ اتفاقی نخواهد افتاد. پیامی که دریافت می کنیم نیز همین موضوع را تایید می کند:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 0 }

البته ما می توانیم به جای حداقل (min$) از حداکثر (max$) استفاده کنیم. مثلا:

db.users.updateOne({name: "Pooya"}, {$max: {age: 25}})

این کوئری می گوید اگر سن Pooya کمتر از 25 بود (max یعنی حداکثر بنابراین حداکثر 25 سال یعنی 25 سال و کمتر) سن را روی 25 بگذار. با اجرای این دستور سن Pooya دوباره 25 سال می شود.

اپراتور بعدی ما نیز mul$ است که مخفف multiply و به معنی ضرب کردن است. مثلا اگر بگوییم Pooya دقیقا 10 درصد بزرگ تر شده است، باید آن را در 1.1 ضرب کنیم بنابراین می توانیم از mul$ استفاده نماییم:

db.users.updateOne({name: "Pooya"}, {$mul: {age: 1.1}})

قبل از اجرای این کوئری، Pooya دقیقا 25 سال سن داشت و حالا این 25 در 1.1 ضرب شده است. در حال حاضر سن او برابر مقدار 27.500000000000004 شده است. حتما با خودتان می گویید مگر 25 ضرب در 1.1 نمی شود 27.5؟ پس این همه عدد اعشاری چیست؟ ما فعلا روی این موضوع بحث نمی کنیم اما زمانی که به فصل اعداد برسیم به طور مفصل دلیل ایجاد این پدیده را توضیح خواهم داد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری دوره جامع آموزش MongoDB توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

مقالات مرتبط
آخرین سوالات کاربران
5451218 در 2 سال قبل پرسیده:
ما را دنبال کنید
اینستاگرام روکسو تلگرام روکسو ایمیل و خبرنامه روکسو