یکی دیگر از مفاهیم اصلی که باید در عملیات های write با آن ها آشنا شویم مفهوم atomocity (اتمی بودن کوئری ها) است. برای توضیح این مفهوم فرض کنید یک دستور insert داشته باشیم (البته این دستور میتواند هر دستور رایت دیگری باشد) در اکثر مواقع این دستور بدون مشکل اجرا می شود اما خطا گرفتن در آن ها غیرممکن نیست. منظور من از خطا در این جا خطاهای خاصی است که در هنگام ثبت سند (document) رخ می دهد، یعنی زمانی که سرور MongoDB در حال ثبت دستوری از سمت ما است دچار خطا شده و عملیات متوقف می شود (زمانی که در حال ثبت در مموری است). حالا تصور کنید که سند شما از نوع Embedded Document است و فیلد های مختلفی را در خود دارد. اگر خطا در حین ثبت این سند رخ بدهد ممکن است قسمتی از آن در پایگاه داده ذخیره شود و نیمه انتهایی آن از بین برود. آیا این اتفاق واقعا ممکن است؟
پایگاه داده MongoDB از شما در برابر چنین خطاهایی محافظت می کند و به شما تضمین می دهد که ثبت اسناد شما به صورت atomic (به معنی «اتمی») انجام می شود. اتمی بودن یک تراکنش یا یک عملیات کوئری بدین معناست که یا تمام این عملیات با موفقیت انجام می شود یا تمام آن با خطا روبرو خواهد شد بنابراین اگر سند ما به صورت نصفه در پایگاه داده ثبت شود (در حین عملیات دچار خطا شویم) MongoDB مقدار ثبت شده را حذف می کند تا پایگاه داده به حالت قبل از ثبت داده های ناقص برگردد. به این کار rollback می گوییم (در لغت به معنای برگرداندن به عقب است).
این عملیات در سطح تک داکیومنت انجام می شود یعنی اگر سند ما دارای داکیومنت های تودرتو باشد بالاترین سطح داکیومنت یا داکیومنتِ پدر ملاک انجام عملیات است. بنابراین یا تمام فیلدها و داکیومنت های موجود در داکیومنتِ پدر ثبت می شوند و یا اینکه هیچ کدام از آن ها اجازه ثبت شدن ندارند. این مسئله موضوع جالبی را به ما نشان می دهد. اگر ملاک عمل در سطح داکیومنت می باشد، در دستوراتی مانند insertMany که چند داکیومنت داریم چه اتفاقی می افتد؟ این مسئله را در دو جلسه قبل (مفهوم ordered inserts) بررسی کردیم. اگر یادتان باشد در این نوع دستورات، کوئری ما عملیات را اجرا می کرد تا زمانی که به خطا برخورد کند. حالا مشخص می شود که چرا دستور insertMany بدین شکل عمل می کرد. از آنجایی که ثبت اسناد به صورت اتمی فقط در سطح داکیومنت انجام می شود، اگر چندین داکیومنت داشته باشیم، کل دستور محافظت نمی شود بلکه فقط تک تک داکیومنت ها محافظت می شوند تا به صورت ناقص وارد پایگاه داده نشود. البته مبحث تراکنش ها باقی می ماند که یک نوع استثنا هستند و در فصل های مربوطه در مورد آن ها صحبت خواهیم کرد.
مبحث بعدی ما که بسیار کاربردی می باشد مبحث import کردن داده ها است. یعنی داده هایی را از قبل آماده کرده ایم (مثلاً از یک پایگاه داده دیگر خروجی گرفته ایم) و حالا می خواهیم این داده ها را وارد پایگاه داده ای جدید کنیم. برای شروع باید یک پنجره ترمینال ساده را باز کرده و همچنین باید shell را قطع کنید. می توانید این کار را با بستن پنجره ترمینالِ آن یا فشردن کلید های Ctrl + C انجام بدهید. من فایل json بسیار بزرگی را برای شما آماده کرده ام که باید آن را از این لینک دانلود کنید. این فایل شامل داده های بسیار زیادی در مورد برنامه های تلویزیونی می باشد و ما می خواهیم آن را وارد پایگاه داده خودمان کنیم. در قدم اول باید این فایل را در یک پوشه قرار دهید و سپس پنجره ترمینال خود را در همان پوشه باز کنید. اگر از ویندوز استفاده می کنید برای این کار باید کلید shift را نگه داشته و در یک جای خالی درون پوشه کلیک راست کنید. سپس گزینه open command window here را بزنید تا ترمینال در همان پوشه باز شود. اگر از Cmder در ویندوز استفاده می کنید یا از کاربران مک و لینوکس هستید، باید از دستور cd برای مسیر دهی به ترمینال استفاده کنید.
مثال برای مک:
cd ~/Users/Amir/myImport
مثال برای ویندوز:
cd Users\Amir\myImport
همچنین کاربران ویندوز اگر فایل را در درایو دیگری به جز C قرار داده اند باید از دستور زیر برای تغییر آدرس ترمینال استفاده کنند:
cd /d D:\MyAPP\MongoDB\myImport
اپراتور d/ به شما اجازه می دهد به درایور های دیگر بروید. حالا دستور زیر را اجرا می کنم تا اطلاعات جدید را import کنم:
mongoimport tv-shows.json -d movieData -c movies --jsonArray --drop
دستور mongoimport به صورت سراسری در سیستم شما قابل دسترس است چرا که MongoDB را به صورت کلی در environment variable ها اضافه کرده بودیم. اولین آرگومان این دستور، نام فایل ما است (tv-shows.Json). در آرگومان دوم باید مشخص کنیم که داده ها قرار است در کدام پایگاه داده وارد شوند. این کار را با نوشتن حرف d و سپس نام پایگاه داده انجام می دهیم. من پایگاه داده ای به نام movieData ندارم بنابراین به صورت خودکار برایم ساخته خواهد شد. در مرحله بعد باید مشخص کنیم که داده های ما قرار است در کدام collection وارد شوند. این کار با نوشتن حرف c و سپس نام collection انجام می شود. این کالکشن نیز در پایگاه داده من وجود ندارد بنابراین به صورت خودکار ساخته خواهد شد. سپس دستور jsonArray-- را داریم. دلیل نوشتن این دستور این است که فایل ما یک آرایه از انواع داده های مختلف است بنابراین حتماً باید از این دستور استفاده کنیم تا MongoDB بداند که فایل ما حاوی مجموعه ای از اطلاعات است. اگر فایل شما فقط یک سند داشت نباید این گزینه را قرار بدهید. در نهایت دستور drop-- را داریم که به MongoDB میگوید اگر چنین collection ای از قبل وجود داشت، آن را حذف کن و این داده های جدید را به جای آن قرار بده (یعنی کالکشن یک بار حذف شده و دوباره ساخته می شود). اگر این دستور را در کوئری خود قرار ندهید، داده های جدید به داده های قدیمی پیوست می شوند و هیچ کدام از داده های قدیمی حذف نخواهد شد.
نتیجه اجرای کد بالا بدین شکل است:
2020-04-08T12:22:08.698+0430 connected to: mongodb://localhost/ 2020-04-08T12:22:08.706+0430 dropping: movieData.movies 2020-04-08T12:22:09.060+0430 240 document(s) imported successfully. 0 document(s) failed to import.
بنابراین 240 سند یا document را اضافه کرده ایم!
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.