簡體   English   中英

在 Go 中使用頁碼和限制進行分頁的好做法是什么?

[英]What is a good Practice for Pagination using Page Number & Limit in Go?

我使用頁碼和限制在 Go 中創建了分頁。 其中Limit & Page Number are INT

我創建了如下分頁:

MONGO_SESSION.Find(nil).Skip(pageNumber*limit).Limit(limit).Sort("_id").All(&RETURN_STRUCT)

它工作正常。 但是當我發送頁碼或限制為零時。 默認情況下 mongo DB 返回所有記錄,因為沒有什么可以跳過和限制的。

所以我的問題是,在零限制和零頁碼的情況下什么是好的做法。

練習 1:發送所有數據。 不要發送錯誤響應。

實踐二:發送錯誤響應說“頁數和限制不能為零”

注意:我不能硬編碼限制或頁碼。

任何建議將不勝感激。

這個問題有點基於意見(因此對於 StackOverflow 來說有點偏離主題),但我認為一些建議或一般實踐可能對其他人有所幫助和有用。 因此,以下答案是我的意見。

您作為服務器應用程序的開發人員負責服務器的安全和保障,以及服務器資源的利用。 作為開發人員,您應該在必要的最低限度內信任客戶。

也就是說,當客戶未能指定限制(意外或故意)時發送所有文檔是處理這種情況的最糟糕的方式。 這就像尖叫:“嘿,客戶和黑客,這是一個端點,如果你想對我的服務器進行DoS 攻擊,只需多次調用這個端點”。

為了保護你的服務器,你應該有一個安全限制,即使是“limit”參數,因為允許它的任何值可能同樣糟糕:僅僅因為你強制客戶端指定一個限制並不能保護你的服務器,“壞”客戶也可以發送一個像1e9這樣的限制,它很可能包括你的所有文件。

我的建議是始終有有意義的默認值安全限制 應始終記錄默認值,安全限制不是那么重要(但也可以記錄)。

那么你應該如何處理它:

  1. 如果缺少限制,則應用默認值。 如果您不能擁有默認值,請跳過此步驟(盡管必須有充分的理由不擁有/允許默認值)。

  2. 應根據安全限制檢查限制。 如果超過安全值,則使用安全限值(最大允許限值)。

  3. 如果服務器“有權”更改請求的限制(例如,在缺少限制時使用默認值,或根據安全限制設置限制),則服務器應將實際用於服務的限制返回給客戶端請求。

關於高效的 MongoDB 分頁:我只建議將Query.Skip()Query.Limit()用於“小”文檔計數。 對於隨文檔數量“縮放”的高效分頁,請查看此問題+答案: 使用 mgo 在 MongoDB 中進行有效分頁

我相信,分頁應該只用於集合大小很大的情況(否則只需一次顯示所有數據,根本不要擺弄分頁)。

但是,如果集合相當大,那么發送所有數據是一個壞主意。

“skip”語句還有一個問題(雖然它不是 mongo 獨有的):為了跳過 N 條記錄,db 必須進行完整掃描(在 mongo 的情況下進行完整集合掃描),因此需要更多時間獲取頁面 N + 1 的結果而不是頁面 N。

現在,為了處理它,有一個“技巧”:根本不要使用 skip,而是“記住”最后一個文檔 id(無論如何它已經被索引,無論如何你都按_id排序)。 然后查詢將是(偽代碼,因為我不會說“Go”):

  • 對於第一個查詢: Find().sort(_id).limit(limitSize)

  • 對於后續查詢: Find ().where(_id > lastMemorizedId).sort(_id).limit(limitSize)

我也面臨同樣的問題。 我更喜歡發送錯誤響應而不是顯示所有數據。

因為如果 DB 必須發送所有數據,這對 DB 來說是一項繁重的事務。 在小集合上,它工作正常,但對於大集合,它會掛起 DB。

所以發送錯誤響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM