为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中使用页码和限制进行分页的最佳做法是什么?

在 Go 中使用页码和限制进行分页的最佳做法是什么?

Go
繁花不似锦 2023-04-04 16:59:45
我使用页码和限制在 Go 中创建了分页。在哪里Limit & Page Number are INT我创建了如下分页:MONGO_SESSION.Find(nil).Skip(pageNumber*limit).Limit(limit).Sort("_id").All(&RETURN_STRUCT)它工作正常。但是当我发送页码或限制为零时。默认情况下,mongo DB 返回所有记录,因为没有什么可以跳过和限制的。所以我的问题是,在零限制和零页码的情况下,什么是好的做法。实践一:发送所有数据。不要发送错误响应。实践 2:发送错误响应说“页码和限制不能为零”注意:我不能硬编码限制或页码。任何建议将不胜感激。
查看完整描述

3 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

这个问题有点基于意见(因此对于 StackOverflow 来说有点偏离主题),但我认为一些建议或一般做法可能对其他人有帮助和有用。因此,以下答案是我的意见。

作为服务器应用程序的开发人员,您应对服务器的安全和保障以及服务器资源的利用负责。作为开发人员,您应该在必要的最低限度内信任客户。

也就是说,当客户未能指定限制(无意或有意)时发送所有文件是处理这种情况的最糟糕方法。这就像尖叫:“嘿,客户和黑客,这是一个端点,如果你想对我的服务器进行DoS 攻击,只需调用这个端点几次”。

为了保护您的服务器,即使对于“limit”参数,您也应该有一个安全限制,因为允许它的任何值都可能同样糟糕:仅仅因为您强制客户端指定一个限制并不能保护您的服务器,“bad”客户也可以发送一个限制,比如1e9很可能包括您的所有文件。

我的建议是始终具有有意义的默认值安全限制。应始终记录默认值,安全限制并不那么重要(但也可以记录)。

那么你应该如何处理它:

  1. 如果缺少限制,请应用默认值。如果您不能有默认值,请跳过此步骤(尽管必须有充分的理由不具有/允许默认值)。

  2. 应根据安全限值检查限值。如果超过安全值,则使用安全限制(最大允许限制)。

  3. 如果服务器“有权”更改请求的限制(例如,在缺少限制时使用默认值,或根据安全限制限制限制),服务器应将实际用于服务的限制传达给客户端要求。

关于高效的 MongoDB 分页:我只建议使用Query.Skip()andQuery.Limit()用于“小”文档计数。


查看完整回答
反对 回复 2023-04-04
?
HUX布斯

TA贡献1876条经验 获得超6个赞

我相信,分页应该只用于集合大小很大的情况(否则只是一次显示所有数据并且根本不要摆弄分页)。

但是,如果集合相当大,那么发送所有数据并不是一个好主意。

“skip”语句还有一个问题(虽然它不是 mongo 独有的):为了跳过 N 条记录,数据库必须进行全扫描(如果是 mongo,则为全集合扫描),因此需要更多时间获取第 N + 1 页的结果而不是第 N 页的结果。

现在,为了处理它,有一个“技巧”:根本不要使用 skip,而是“记住”最后一个文档 ID(无论如何它已经编入索引并且您仍然可以排序_id)。然后查询将是(伪代码,因为我不会说“Go”):

  • 对于第一个查询: Find().sort(_id).limit(limitSize)

  • 对于后续查询: Find ().where(_id > lastMemorizedId).sort(_id).limit(limitSize)


查看完整回答
反对 回复 2023-04-04
?
holdtom

TA贡献1805条经验 获得超10个赞

我也遇到了同样的问题。我更喜欢发送错误响应而不是显示所有数据。

因为如果 DB 必须发送所有数据,这对 DB 来说是一项繁重的事务。在小型集合上,它工作正常,但对于大型集合,它会挂起 DB。

所以发送一个错误响应。


查看完整回答
反对 回复 2023-04-04
  • 3 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信