iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
自我挑戰組

被MongoDB用Aggregate暴打的後端小菜雞日記系列 第 3

被MongoDB用Aggregate暴打的後端小菜雞日記-day3-基本使用懶人包

  • 分享至 

  • xImage
  •  

今天要來介紹$sort$skip$limit這三個操作符
在前端打api向後端後資料時,通常如果資料的數量非常的龐大,為了避免對資料庫造成負擔,會做分頁的動作,一次回傳一部分的資料。

例如:我們平常在網購的時候,輸入我們想找的商品關鍵字,找到有180筆符合的商品,這些商品可能會按照價格的高低進行排序,並且以分頁的形式呈現給消費者。

當看完第一頁找不到理想的商品,我們就會按第二頁,載入不同的商品讓我們選擇。

通常在做分頁時,前後端都會約定好特定的參數,指定目前要拉的商品資料,是第幾頁、一頁要拉幾筆資料。

假設我們現在資料庫內有這些商品資料

  { id: 1, name: "滑鼠", price: 600, amount: 23 },
  { id: 2, name: "傳輸線", price: 100, amount: 34 },
  { id: 3, name: "mp3", price: 2300, amount: 2 },
  { id: 4, name: "吹風機", price: 6500, amount: 10 },
  { id: 5, name: "筆電架", price: 900, amount: 4 },
  { id: 6, name: "貼紙", price: 100, amount: 87 },
  { id: 7, name: "耳機", price: 2900, amount: 44 },
  { id: 8, name: "滑鼠墊", price: 600, amount: 46 },
  { id: 9, name: "鍵盤", price: 1000, amount: 24 },
  { id: 10, name: "USB", price: 600, amount: 23 }

如果要找第一頁,裡面有4筆資料,商品必須按照價格由低到高排序,如果價格一樣,就按照商品數量由多到少排序
我們會用以下指令。

product.aggregate([
  { $sort: { price: 1, amount: -1 } },
  { $limit: 4 }
]);

其中$sort的指令代表是排序,你可以決定用來排序的欄位,1和-1代表排序的方向,1是由小到大排,-1由大到小排,用來進行排序的欄位可以不只有一個,會先從最左邊的欄位(price)開始排序,如果剛好value相同,才會由下一個欄位(amount)進行排序。

因此經過{ $sort: { price: 1, amount: -1 } }排序後的資料會是

  { id: 6, name: "貼紙", price: 100, amount: 87 },
  { id: 2, name: "傳輸線", price: 100, amount: 34 },
  { id: 8, name: "滑鼠墊", price: 600, amount: 46 },
  { id: 1, name: "滑鼠", price: 600, amount: 23 },
  { id: 10, name: "USB", price: 600, amount: 23 },
  { id: 5, name: "筆電架", price: 900, amount: 4 },
  { id: 9, name: "鍵盤", price: 1000, amount: 24 },
  { id: 3, name: "mp3", price: 2300, amount: 2 },
  { id: 7, name: "耳機", price: 2900, amount: 44 },
  { id: 4, name: "吹風機", price: 6500, amount: 10 }

接下來我們會用$limit指令,限制資料回傳的筆數只有4筆,最後回傳前四筆商品做為第一頁。

  { id: 6, name: "貼紙", price: 100, amount: 87 },
  { id: 2, name: "傳輸線", price: 100, amount: 34 },
  { id: 8, name: "滑鼠墊", price: 600, amount: 46 },
  { id: 1, name: "滑鼠", price: 600, amount: 23 },

那如果我要第二頁的資料呢? 必須多加$skip的指令跳過前4筆,第一頁的資料。
這裡特別注意的是,$skip必須放在$limit的前面,因為我們將資料排序完後,必須先跳過第一頁的資料,再回傳剩下資料中的前四筆。

product.aggregate([
  { $sort: { price: 1, amount: 1 } },
  { $skip: 4 },
  { $limit: 4 }
]);

回傳的資料會是

  { id: 10, name: "USB", price: 600, amount: 23 },
  { id: 5, name: "筆電架", price: 900, amount: 4 },
  { id: 9, name: "鍵盤", price: 1000, amount: 24 },
  { id: 3, name: "mp3", price: 2300, amount: 2 }

番外:如果剩下的資料少於$limit限制回傳的數量呢?
例如:我們要找第三頁的商品資料,前面8筆資料用$skip跳過了,只剩下最後兩筆。
那當然是指回傳最後這兩筆資料,因為$limit是限制回傳資料的數量,不可以超過指定的數值,而非要求回傳的數量!

本篇文章同步放在我的部落格,大家有空可以進來逛逛


上一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day2-什麼是aggregate pipeline?
下一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day4-用$match篩選資料
系列文
被MongoDB用Aggregate暴打的後端小菜雞日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言