برنامه نویسی

مرتب سازی بر روی آرایه با فهرست چند کلید

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

مجموعه داده ای که وارد کردم برای جستجوی نماهای ویدیو طراحی نشده است ، فقط برای ذخیره آنها در هر ویدیو. این شامل دو آرایه است: یکی برای روزها (“Day.data”) و دیگری برای تعداد بازدید روزانه (“Views.Daily.Data”). این طرح برای بازیابی همه آمار برای یک فیلم خاص به یکباره بود. با این حال ، این سری وبلاگ با هدف نشان دادن چگونگی یک مدل سند MongoDB می تواند از طریق فهرست های دوم ، بدون استفاده از طرح مجموعه ای ، بدون استفاده از مجموعه مجموعه های اضافی پشتیبانی کند.

الگوی دسترسی: فیلم هایی با بالاترین نماهای روزانه

این ساده است ، فقط با استفاده از نماد نقطه ای برای تعریف مسیر ، یک شاخص را در مجموعه داده های روزانه نمای روزانه ایجاد کنید:

db.youstats.createIndex({ 
 "views.daily.data": -1      , // for Sort on maximum daily view
 commentsNumber: 1           , // for additional filter on comments
}); 
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

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

  • یک مرتب سازی نزولی اسناد را با بالاترین ارزش در آرایه سفارش می دهد.
  • مرتب سازی صعودی اسناد را با کمترین مقدار در آرایه ثبت می کند.

راه دیگر برای فکر کردن در مورد آن این است که اسکن شاخص از اولین کلید با هر سند استفاده می کند و دیگران را پرش می کند. در اسکن رو به جلو با یک شاخص نزولی ، بیشترین ارزش است.

برای یافتن اسناد 3 برتر با نمایش روزانه ، در اینجا یک پرس و جو ساده وجود دارد:

db.youstats.find({},{
  author: 1               ,
  title: 1                ,
  duration: 1             ,
  type: 1                 ,
  publishedDate: 1        ,
  commentsNumber: 1       ,
  // "views.daily": 1        ,
  // "day": 1                ,
}).sort({
  "views.daily.data": -1 
}).limit(3)

[
  {
    _id: 'ASO_zypdnsQ',
    commentsNumber: 1122436,
    author: 'officialpsy',
    publishedDate: '2013-04-13T11:59:04.000Z',
    title: 'PSY - GENTLEMAN M/V',
    duration: 234,
    type: 'video/3gpp'
  },
  {
    _id: 'My2FRPA3Gf8',
    commentsNumber: 1125301,
    author: 'MileyCyrusVEVO',
    publishedDate: '2013-09-09T16:00:38.000Z',
    title: 'Miley Cyrus - Wrecking Ball',
    duration: 222,
    type: 'application/x-shockwave-flash'
  },
  {
    _id: 'YoB8t0B4jx4',
    commentsNumber: 39370,
    author: 'SA Wardega',
    publishedDate: '2014-09-04T14:28:22.000Z',
    title: 'Mutant Giant Spider Dog (SA Wardega)',
    duration: 239,
    type: 'video/3gpp'
  }
]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اسناد نشان می دهد که یکی از داده های روزانه نمایش در آرایه بالاترین مقدار را دارد. به عنوان مثال ، نتیجه 3 این بود:

  {
    _id: 'YoB8t0B4jx4',
    commentsNumber: 39370,
    author: 'SA Wardega',
    publishedDate: '2014-09-04T14:28:22.000Z',
    title: 'Mutant Giant Spider Dog (SA Wardega)',
    day: {
      data: [
        Long('1409788800000'), Long('1409875200000'), Long('1409961600000'), Long('1410048000000'), Long('1410134400000'), Long('1410220800000'), Long('1410307200000'), Long('1410393600000'), Long('1410480000000'), Long('1410566400000'), Long('1410652800000'), Long('1410739200000'), Long('1410825600000'), Long('1410912000000'), Long('1410998400000'), Long('1411084800000'), Long('1411171200000'), Long('1411257600000'), Long('1411344000000'), Long('1411430400000'), Long('1411516800000'), Long('1411603200000'), Long('1411689600000'), Long('1411776000000'), Long('1411862400000'), Long('1411948800000'), Long('1412035200000'), Long('1412121600000'), Long('1412208000000'), Long('1412294400000'), Long('1412380800000'), Long('1412467200000'), Long('1412553600000'), Long('1412640000000'), Long('1412726400000'), Long('1412812800000'), Long('1412899200000'), Long('1412985600000'), Long('1413072000000'), Long('1413158400000'), Long('1413244800000'), Long('1413331200000'), Long('1413417600000'), Long('1413504000000'), Long('1413590400000'), Long('1413676800000'), Long('1413763200000'), Long('1413849600000'), Long('1413936000000'), Long('1414022400000'), Long('1414108800000'), Long('1414195200000'), Long('1414281600000'), Long('1414368000000')
      ]
    },
    duration: 239,
    type: 'video/3gpp',
    views: {
      daily: {
        data: [
          2964062, 17799094, 19526335, 14604160, 9606241, 5959851,  4090643,  3419126,  2907521, 2626169, 2195691,  1518943,  1251086,  1128994,  958318, 861349,   785797,   628364,   506154,  564079, 445417,   474349,   498093,   589038,  444256, 363379,   329318,   313375,   333627,  335226, 354050,   322087,   239715,   228562,  213420, 201771,   213078,   247715,   228587,  183759, 168511,   169992,   199282,   326091,  347602, 335237,   290271,   242939,   223959,  219971, 249009,   277773,   279301,   220609
        ]
      }
    }
  }

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از آنجا که این در چند میلی ثانیه در چند ثانیه اجرا شد ، بدیهی است ، و میلیون ها سند را اسکن نکرد و از این شاخص به طور کارآمد استفاده کرد. بررسی این کار با توضیح () آسان است:

db.youstats.find({},{
  author: 1               ,
  title: 1                ,
  duration: 1             ,
  type: 1                 ,
  publishedDate: 1        ,
  commentsNumber: 1       ,
  "views.daily": 1        ,
  "day": 1                ,
}).sort({
  "views.daily.data": -1 
}).limit(3).explain("executionStats").executionStats

...
  nReturned: 3,
  executionTimeMillis: 1,
  totalKeysExamined: 7,
  totalDocsExamined: 3,
...
    stage: 'LIMIT',
    nReturned: 3,
    limitAmount: 3,
...
      stage: 'PROJECTION_SIMPLE',
      nReturned: 3,
...
        stage: 'FETCH',
        nReturned: 3,
...
          stage: 'IXSCAN',
          nReturned: 3,
          keyPattern: { 'views.daily.data': -1, commentsNumber: 1 },
          isMultiKey: true,
          multiKeyPaths: {
            'views.daily.data': [ 'views.daily.data' ],
            commentsNumber: []
          },
          direction: 'forward',
          indexBounds: {
            'views.daily.data': [ '[MaxKey, MinKey]' ],
            commentsNumber: [ '[MinKey, MaxKey]' ]
          },
          keysExamined: 7,
          seeks: 1,
          dupsTested: 7,
          dupsDropped: 4
        }
      }
    }
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این شاخص حاوی ورودی برای هر “views.daily.data” از همه اسناد است که از بالاترین نمای روزانه شروع می شود. اولین کلید مورد بررسی ، ضبط سند را با بالاترین نمای روزانه برمی گرداند. کلید بعدی ممکن است با همان فیلم مطابقت داشته باشد ، که ممکن است در یک روز دیگر یا یک فیلم دیگر داشته باشد. برای بازگشت 3 سند مجزا ، اسکن باید ضبط تکراری را از بین ببرد. در اینجا 4 کپی کاهش یافته است به طوری که 3+4 = 7 کلید در کل خوانده شده است.

MongoDB از شاخص های Wiredtiger B-Tree نه تنها برای یافتن مقادیر خاص ، بلکه برای حرکت به طور کارآمد از طریق محدوده مرزهای شاخص استفاده می کند. حتی اگر ما کمتر خوش شانس بودیم و مجبور شدیم 365 کلید در هر سند را بررسی کنیم ، خواندن یک هزار ورودی شاخص هنوز سریع است ، زیرا فقط 3 سند باید از آن استفاده شود.

الگوی دسترسی: فیلم هایی با کمترین بازدید روزانه و بدون نظر

همین شاخص همچنین می تواند فیلم ها را با کمترین نماهای روزانه شناسایی کند. برای حذف افراد بدون داده ، من فقط ورودی هایی را در دسترس قرار می دهم:

db.youstats.find({
  "views.daily.data": { $exists: true } ,
  "commentsNumber": { $lt: 1 } ,
},{
  author: 1               ,
  title: 1                ,
  duration: 1             ,
  type: 1                 ,
  publishedDate: 1        ,
  commentsNumber: 1       ,
  "views.daily": 1        ,
  //"day": 1                ,
}).sort({
  "views.daily.data": 1 
}).limit(3)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این پرس و جو ممکن است نتایج مفیدی را به همراه نکند ، زیرا فیلم ها را بدون هیچ دیدگاهی در یک روز معین باز می گرداند ، حتی اگر قبلاً دیدگاه های زیادی داشته باشند. به یاد داشته باشید ، صعودی مرتب سازی پایین ترین مقدار میدان را در آرایه بازیابی می کند ، در حالی که نزولی مرتب سازی بالاترین را بازیابی می کند.

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

برای کسب اطلاعات در مورد نحوه رفتار مرتب سازی با داده های مختلف ، لطفاً به مستندات مراجعه کنید: مقایسه/مرتب سازی

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا