页面大小如何在嵌套OData查询中工作



假设我们想要执行以下odata查询:

api/accounts?$expand=contacts

假设我们有3个帐户(例如a1、a2、a3),每个帐户有3个联系人。因此,如果我们定义">odata.maxpagesize=2";并执行上述查询,根据OData标准会得到什么结果。

选项-1

a1
- c11
- c12
- (odata.nextlink for c13)

a2
- c21
- c22
- (odata.nextlink for c23) 
(odata.nextlink for a3)

选项-2

a1
- c11
- c12
- (odata.nextlink for c13)
(odata.nextlink for a2, a3)

对于pagesize=2,这看起来可能很容易,但假设pagesize=5000,那么它会返回吗:

选项-15000个帐户,每个帐户嵌套5000个联系人。因此,从这个角度来看,它将拥有25000000张记录。

选项-21个帐户,并为该帐户嵌套5000个联系人。因此,从这个角度来看,它将有5000张记录。

--------更新-2-------------------------

我们只是对Option-1有点犹豫,因为用户可以查询多个展开,这可能会导致结果太大。例如,如果用户查询:accounts?$expand=contacts($expand=callHistory)

因此,考虑maxPageSize为100的选项1,如果我们在所有嵌套级别返回记录直到maxPageSize,那么它将返回100(账户)*100(每个账户的联系人)*100)(每个联系人的呼叫日志)=100000个实体

若用户在进一步的嵌套级别上使用$expand,则记录的数量将呈指数级增长。请告诉我我的分析是否正确。

另一方面,选项-2可能接近您的建议。在这里,我们将对嵌套结果进行计数,并检查实体计数是否超过页面大小。因此,在那之后,我们可以在任何适用的地方返回nextlink。

如果您能重新验证我们的方法,那就太好了。:)

任一选项在技术上都符合规范。MaxPageSize是首选项(即对服务的提示),并且允许服务返回更多/更少,只要它正确地为不完整的集合返回nextLink。

因此,例如,一个服务也可以查看5000的maxpageSize,并决定返回前1000个父级,每个父级最多有5个嵌套结果。或者,它可以完全忽略maxpagesize,并返回200个只有嵌套资源下一个链接的父级。或

我认为最好的消费者体验更接近选项1,在选项1中,服务返回一些a(小于或等于maxpagesize,可能基于嵌套结果的数量/级别),每个都有一些b(同样,可能基于嵌入结果的数量或级别,最高可达maxpagesize)

不确定这是否有帮助?

---对更新2的响应---对你的分析是正确的。而且,它比这更复杂——用户可以在每个级别$expanded多个属性,所以你要么最终将页面大小乘以每个级别$explanded属性的数量,要么你必须决定如何将页面大小请求的结果划分到每个级别的所有$expande集合中。

正如我所说,选项2是有效的,而且可能很容易实现(只需读取第一个页面大小的记录,然后停止),但对于试图了解数据(即在视觉显示中)然后在适当的地方进行深入了解的消费者来说,它可能不那么友好。

这在一定程度上取决于消费场景。选项2优化为仅在请求的总记录数超过maxpagesize的情况下进行分页,但(在极端情况下)结果的第一页不是很有代表性。

另一方面,如果目标是让某人查看/浏览数据,在适当的地方钻取,然后根据一些静态值限制嵌套集合(例如,每个嵌套集合的前5条记录),然后使用maxpagesize来限制顶级记录或记录总数,这可能会更方便用户。唯一的缺点是,即使完整结果小于maxpagesize,也可能为嵌套集合引入分页。

您可能还需要考虑哪种实现更高效。例如,如果您正在构建一个查询以从底层存储中获取数据,那么为每个嵌套集合请求固定的最大记录数可能会更有效,而不是请求嵌套集合的所有数据,然后在读取完所需数据后将其余数据丢弃。

同样,请记住,计算不一定要精确。maxpagesize只是对服务的一个提示。该服务不需要返回确切的计数,所以不要过于拘泥于试图准确计算将返回的记录数量。

个人偏好:如果我有潜在的大嵌套结果,我可能会倾向于基于一些静态值来限制它们。它使结果更加可预测和统一,并提供了更好的数据表示。

最新更新