میشه لطفا درباره تفاوت lookup ، populate بگید و کلا زمانی که قراره رو lookup شرط بخوره و query ها پیچیده بشن هم آموزش بدید من الان پیچیده ترین query ها رو تو اس کیو ال راحت میزنم ولی همونو بخوام مونگو کنم واقعا گاهی نمیتونم مثلا query که جوین باشه شرط داشته باشه group & having اس کیو ال هم داشته باشه یه همچین مثالی بزنید ممنون میشم
خب بذارید من توضیح بدم.
در خط زیر :
let: { order_item: "$item", order_qty: "$ordered" }
ما با استفاده از let برای lookup میایم و متغییر تعریف می کنیم، در واقع این متغییرها فقط برای استفاده توی pipeline که در داخل lookup نوشته میشه استفاده میشه. برای دسترسی به فیلد های orders از علامت $ استفاده شده مثلا $item و این یعنی فیلد آیتم بیاد و داخل order_item قرار بگیره و برای متغییر بعدی هم همین طور.
حالا بیایم و pipeline رو بررسی کنیم:
[
{ $eq: [ "$stock_item", "$$order_item" ] },
{ $gte: [ "$instock", "$$order_qty" ] }
]
در این فیلد ها که با $ مشخص شدن متعلق به یک کالکشن دیگه هستن به اسم warehouse و برای این که از متغییر های بخش let استفاده کنیم اونها رو با $$ مشخص می کنیم که در این جا بر اساس expr های که در pipeline داریم ازشون استفاده شده.
برای مساله خودتون به نظرم از driver شروع کنید و با orders یک aggregate ایجاد کنید و در بخش lookup در بخش متغییر ها تاریخ یک هفته پیش رو تعریف کنید، حالا در بخش pipeline می تونید توی بخش match و expr ها از gte بر روی متغییر تعریف شده استفاده کنید و در نهایت هم با $sum مقادیرشون رو جمع کنید. اینطوری میزان درآمد روزانه و ماهانه و هفتگی و سالیانه یک راننده رو می تونید مشخص کنید.
سلام خدمت شما. lookup یک بخش از بحث aggregation ها در خود mongodb هست در حالی که populate یک متد بر روی mongoose و عملا populate در پشت صحنه از چندین کوئری مجزا برای تطبیق reference های تعریف شده در Model استفاده میکنه. اگر می خواید کوئری های پیچیده داشته باشید باید از aggregate framework خود mongo استفاده کنید که به صورت pipeline عمل می کنه و این یعنی در ابتدا مثلا 10000 رکورد رو انتخاب می کنه و بعدش group رو اجرا می کنه و در نهایت هم مثلا project میکنه. شما بر اساس نوع داده هایی که میخواین می تونید pipeline های کمتر یا بیشتری داشته باشید. از این لینک می تونید راهنمای aggregate framework رو ببینید.
من با aggregate کار کردم مشکلم دقیقا تو همون pipeline هست زمانی که قراره دوتا collection با هم جوین بشن و شرط بخوره تو pipeline و دیگه به جا lookup باید let بزاریم ست کردن اینا واقعا واسم سخت بود و داکیومنت قبلا دیدم متوجه نشدم واسه همین گفتم تو یه مثال اگه توضیح بدید ممنون میشم
این مثال رو نگاه کنید و بگید کجاش براتون مشکله :
db.orders.insert([
{ "_id" : 1, "item" : "almonds", "price" : 12, "ordered" : 2 },
{ "_id" : 2, "item" : "pecans", "price" : 20, "ordered" : 1 },
{ "_id" : 3, "item" : "cookies", "price" : 10, "ordered" : 60 }
])
db.warehouses.insert([
{ "_id" : 1, "stock_item" : "almonds", warehouse: "A", "instock" : 120 },
{ "_id" : 2, "stock_item" : "pecans", warehouse: "A", "instock" : 80 },
{ "_id" : 3, "stock_item" : "almonds", warehouse: "B", "instock" : 60 },
{ "_id" : 4, "stock_item" : "cookies", warehouse: "B", "instock" : 40 },
{ "_id" : 5, "stock_item" : "cookies", warehouse: "A", "instock" : 80 }
])
db.orders.aggregate([
{
$lookup:
{
from: "warehouses",
let: { order_item: "$item", order_qty: "$ordered" },
pipeline: [
{ $match:
{ $expr:
{ $and:
[
{ $eq: [ "$stock_item", "$$order_item" ] },
{ $gte: [ "$instock", "$$order_qty" ] }
]
}
}
},
{ $project: { stock_item: 0, _id: 0 } }
],
as: "stockdata"
}
}
])
اونجاهایی که یک $ گذاشته یا 2تا اول درک نمیکنم یعنی چی دوم کلا let که میخوایم بزاریم.
اگه بخوام چیزی که تو پروژه شرکت خودم درگیرش بودم و چون نتونستم کلا query ساده زدم و بعد توی جی اس هندلش کردم این بود که پروژه ما پکیج دلیوری هست یه کالکشن order , driver داریم و قرار بود من بیام هزینه دریافتی هر راننده به صورت هفتگی درارم که خوب من گروپ کردم رو هفته ولی مشکل اونجا بود واسم که این سه نوع تاریخ میخورد cancel, delivered, return یه ابجکت تایم داره که سه تا از فیلداش اینا هستن و من شرط date نمیتونسم رو گروپم اعمال کنم هیچ جوری من نتونسم این تو مونگو اکی کنم
همچین خروجی بستگی به فیلد هایی داره که توی project انتخاب می کنید، طیص چیزی که گفتم فیلد های راننده و اون داده های داخل lookup که با as مشخص میشن در خروجی نوشته میشه.
خوب باید رو هر هفته group بشه ولی فک میکنم اون شرطی که شما گفتید این گروپ انجام نمیده و مشکل اصلی من این بود که وقتی میخواستم گروپ بزنم از این کد که پایین میزارم استفاده کرده بودم ولی نمیخواستن رو تایم ایجاد باشه رو اون 3تا تایمی که گفتم تو پیامای قبلی باید این گروپ انجام میشد و من نمیدونسم اینو چه جوری رو این گروپم اعمال کنم
{
$project: {
numWeek: { $week: '$time.create' },
year: { $year: '$time.create' },
cost: 1,
}
},
{
$group: {
_id: { year: '$year', numWeek: '$numWeek' },
costValue: {
$sum: '$cost.total'
},
countOrder: { $sum: 1 }
}
}
شما توی order سه تا فیلد تایم دارید، یعنی باید از هر سه تا استفاده کنید؟
تایم یه ابجکت هست که 4تا فیلد داره create, pickup,deliver,return , خود کنسل هم یه فیلد دیگه دیتابیس هست حالا ما فقط orderهایی که status اونا یکی از این حالت ها deliver,return , cancel باشه باید بیاریم , این order ها طبیعی یکیشون time.deliver داره یکی time.return و من نمیدونسم گروپ رو چی بزنم که بتونه هفته ها رو گروپ کنه
به نظرم در طراحی دیتابیس اگر فیلد ها جدا می شد بهتر بود، به هر حال درمرحله اول با match سفارش هایی که در اون چند وضعیت هستند رو فیلتر کنید و بعدش با group به اون مقادیر برسید، چون گروه بندی بر اساس هفته است حتما باید بازه شروع و پایان رو براش در نظر بگیرید مثلا از 5 هفته پیش.