در این قسمت می خواهیم در رابطه با متدی صحبت کنیم که به شما اجازه می دهد document های مرتبط از طریق reference ها را در هم ادغام کنید. این متد که متد lookUp است یکی از کاربردی ترین متد های ما می باشد چرا که در بسیاری از اوقات پایگاه داده را با reference ها طراحی می کنیم اما بعدا پشیمان می شویم و می خواهیم از embedded document ها استفاده کنیم.
ما در جلسه قبل دو collection به نام های authors و books داشتیم که books به شکل زیر بود:
"_id" : ObjectId("5e8882355159280df164b054"), "name" : "My favorite Book", "authors" : [ ObjectId("5e8882d85159280df164b055"), ObjectId("5e8882d85159280df164b056") ] }
همانطور که مشخص است ما در اینجا از reference ها استفاده کرده ایم. حالا فرض کنید که می خواهیم کتاب ها را به همراه اطلاعات نویسنده ها و نه id هایشان دریافت کنم. برای این کار باید از متد aggregate (به معنی «جمع کردن» یا «اجتماع») استفاده کنیم. ما هنوز در مورد این متد چیزی نگفته ایم و من هم نمی خواهم این جلسه را به متد aggregate اختصاص بدهم (در فصل های آینده به طور مفصل آن را بررسی می کنیم). فعلا این قسمت را نادیده بگیرید. برای ادغام اطلاعات نویسنده ها و کتاب ها و دریافت آن ها به صورت یکجا می گوییم:
db.books.aggregate([{$lookup: {from: "authors", localField: "authors", foreignField: "_id", as: "creators"}}]).pretty()
همانطور که می بینید باید یک آرایه را به متد aggregate پاس بدهیم. سپس هر document یک «مرحله» به حساب می آید و از آنجایی که کار ما فقط یک مرحله است من فقط یک document را درون این آرایه تعریف کرده ام. سپس باید lookup$ را نوشته و به عنوان مقدار، یک document را پاس بدهید. یادتان باشد که ما می خواهیم اطلاعات دو collection را در هم ادغام کنیم بنابراین باید مشخص کنیم کدام اطلاعات و کدام collection ها. این موضوع کار lookup است و شامل چهار فیلد اصلی است:
نکته مهم: این کد برای دریافت داده ها است بنابراین زمانی که آن ها اجرا کنید واقعا مقادیر موجود در authors و book را در هم ادغام نمی کند، بلکه یک document جدید را بر اساس شرط ما ساخته و آن را به ما پاس می دهد. collection های ما و document های ما هیچ گونه تغییری نخواهند کرد (این متد فقط یک متد read یا خواندن اطلاعات است).
از آنجایی که این متد قرار است اطلاعات را به ما پاس بدهد، در انتهای آن pretty را گذاشته ام تا اطلاعات را به شکل خواناتری مشاهده کنیم:
"_id" : ObjectId("5e8882355159280df164b054"), "name" : "My favorite Book", "authors" : [ ObjectId("5e8882d85159280df164b055"), ObjectId("5e8882d85159280df164b056") ], "creators" : [ { "_id" : ObjectId("5e8882d85159280df164b055"), "name" : "Amir", "age" : 24, "address" : { "street" : "Main" } }, { "_id" : ObjectId("5e8882d85159280df164b056"), "name" : "Nastaran", "age" : 30, "address" : { "street" : "Far" } } ] }
همانطور که می بینید، در اطلاعات برگشتی فیلد جدیدی به نام creators (نام دلخواه من) به وجود آمده است که حاوی اطلاعات نویسنده ها از یک collection دیگر است! بنابراین این متد بسیار کاربردی است و به ما کمک می کند که به جای اجرای چندین کوئری، اطلاعات خودمان را یکجا دریافت کنیم.
سوال: حالا که این متد را داریم آیا باید همیشه از reference ها استفاده کنیم؟
پاسخ: خیر! طبق مواردی که در جلسات قبل ذکر کردیم اگر روابط بین داده ای شما با embedded document همخوانی دارند حتما از embedded document ها استفاده کنید چرا که فشار کمتری روی پایگاه داده می آورد. دستور aggregate و lookup باید در پس زمینه اطلاعات را ادغام کنند بنابراین نسبت به embedded documents نیاز به منابع بیشتری دارند (این تفاوت ها در حد میلی ثانیه است و نباید فکر کنید که استفاده از aggregate باعث ضربه زدن به وب سایت شما می شود).
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.