首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >网页:通过rest调用检索的分页项的随机集合

网页:通过rest调用检索的分页项的随机集合
EN

Software Engineering用户
提问于 2018-04-22 05:14:49
回答 3查看 119关注 0票数 2

使用.Net web

我有一个网页,它根据通过对api端点的ajax调用应用的筛选值来呈现一组项。

这些项被分页,以便如果用户滚动到页面的底部,那么将对api进行另一次ajax调用,调用下一组条目的所需的页码。

我刚接到一个要求,每天随机抽取所有这些物品。

这里的明显问题是ajax分页-每个调用都检索下一组项,这些项目前很容易,因为这些项的顺序不会改变。因此,如果我们是随机化的,我不能简单地将每个呼叫随机化。

所以我想我需要一些缓存..。

到目前为止,这些想法是:

  1. 午夜时分,所有项目都以某种基于日期的版本键(基于服务器时间)加载到缓存中。
  2. 任何作为第1页项的客户端调用都将始终使用基于日期的键获得缓存的最新版本。页面1响应将将缓存键返回给客户端(连同数据),因此任何对大于1的页面的调用都需要缓存版本键。
  3. 为了处理用户在23:59:59向api发出第1页请求,然后在午夜00:00:30发出第2页请求的可能性,我们可以在36小时后终止缓存版本。然而,新的缓存版本每24小时在午夜创建一次。

这是我正在考虑的总体方向。

有没有人会说些明智的话?

EN

回答 3

Software Engineering用户

发布于 2018-09-19 22:12:17

所以我想我需要一些缓存..。

虽然你的缓存想法并非不可能,但我建议采取更简单的路线。带有自定义逻辑的缓存通常很难正确实现,或者在出错时进行调试。

我刚接到一个要求,每天随机抽取所有这些物品。

“每日”这部分引起了我的注意。如果您总是将列表随机化,您将得到一些复杂的逻辑(正如您已经发现的)。

然而,考虑到洗牌发生在一个相对较慢的周期,有一个更简单的方法来做它。

考虑到他们要求每天进行洗牌,我推断他们特别希望在同一天内为每个用户维持相同的秩序。这种更简单的方法意味着减少开销,以确保每个人在同一天使用相同的混乱订单。

  1. ShuffledOrder int属性添加到类中

代码语言:javascript
运行
AI代码解释
复制
public class Person
{
    public string Name { get; set; }
    public int ShuffledOrder { get; set; }
}

  1. 创造一个工作,运行每午夜,这是洗牌的秩序。其思想是,您总是得到一个从1到N的ShuffleOrder序列(其中N是实体的数量),例如:

代码语言:javascript
运行
AI代码解释
复制
  Name  |  ShuffledOrder
==========================
   Tim  |      3
   Tom  |      2
   Joe  |      1
   Bob  |      4

洗牌算法的一个简单例子:

代码语言:javascript
运行
AI代码解释
复制
var rnd = new Random();
var people = db.People.ToList();
int shuffleOrder = 1;

foreach(var person in people.OrderBy(p => rnd.Next())
{
    person.ShuffledOrder = shuffleOrder++;
}

db.SaveChanges();

请注意,这是一个演示洗牌逻辑的简化示例。为了保持示例的简单性,省略了性能考虑(例如,没有在内存中加载潜在的大量表)。

  1. 从表中检索项时,始终按其ShuffleOrder对它们进行排序

代码语言:javascript
运行
AI代码解释
复制
var pagedList = db.People
                       .OrderBy(p => p.ShuffledOrder)
                       .Skip(pageIndex * pageSize)
                       .Take(pageSize)
                       .ToList();

摘要

  • 在石头上设置洗牌顺序,可以确保你能在你想要的时间内维持洗牌顺序。
  • 此方法不会受到您可能具有的任何其他筛选逻辑的负面影响。
  • 我希望这比对每个调用重新执行随机化器更有性能(即使随机化器是今天的日期)。
  • 它避免了缓存,这往往会使开发和调试复杂化。
票数 2
EN

Software Engineering用户

发布于 2018-04-22 13:12:38

您可以为已经加载的每个元素包含一些唯一的键,并将其与新的Ajax请求一起发布,然后选择一些随机项,除了接收到的列表中的项。有点像

代码语言:javascript
运行
AI代码解释
复制
SELECT top 10 * from myTable where Not Id in ('id1','id2'...) order by myRandomizer
票数 0
EN

Software Engineering用户

发布于 2018-09-19 23:09:59

不要使DBE的工作变得多余(缓存),也不要让客户端的实现细节变得过于复杂(缓存密钥)。

您的DBE已经有了一些工具来管理一个好的缓存(甚至对于缓存失效),创建一个使用当前日期作为标准排序的视图,并对视图而不是表进行分页。

DBE缓存和索引将完成其余的工作。您可以先尝试:

  • 读取视图时查询中的简单ORDER BY,但并不是每个DBE对此用例都足够有效。
  • 如果受支持,则在视图中使用display_index,该视图使用一个随机数计算,该随机数以当前日期为种子,对已由另一个稳定列(例如id)排序的查询进行排序。

无论如何,从最简单的开始和度量(并调优您的索引!)

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/369791

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文