如何快速过滤满足日期范围条件的对象

Posted

技术标签:

【中文标题】如何快速过滤满足日期范围条件的对象【英文标题】:How to fast filter objects that satisfy date range condition 【发布时间】:2011-10-21 13:57:16 【问题描述】:

我有大量的对象

public class Restriction

    // which days this restriction applies to
    public DateTime From  get; set; 
    public DateTime To  get; set; 

    // valid applicable restriction range
    public int Minimum  get; set; 
    public int Maximum  get; set; 

我可以拥有

IList<Restricton> restrictions;

然后搜索在特定日期应用的限制

restrictions.Where(r => day >= r.From && day <= r.To);

问题

我想使用IList&lt;T&gt; 并不是最好的选择,因为我会针对这些限制进行大量搜索,并且每次我调用 LINQ 方法.Where 时都会枚举和过滤整个集合。

根据我所掌握的 SQL 知识,我知道表扫描总是比索引扫描差,所以我想在这里应用类似的逻辑。我宁愿以更智能的方式过滤,而不是每次都枚举整个集合。

问题

有什么更好(更快)的方法来枚举我的限制,这样我的算法就不会在每次我想过滤掉一些限制时都枚举它们?

我在考虑IDictionary&lt;K,V&gt;,但它仍然需要扫描它们,因为我的限制不是每天设置,而是每天范围。

你有什么建议?

【问题讨论】:

这里的第二个答案可以帮助吗:***.com/questions/1042087/… 见:Interval Tree 【参考方案1】:

考虑按From 对列表进行排序 - 然后您可以快速执行二进制搜索以找到可能适用于From 的限制子集。

您可能还希望获得按To 排序的列表的第二个副本-然后,您可以再次执行二进制搜索以查找我适用于To 的限制子集。使用这两个列表,您可以执行 both 二进制搜索,并找出哪个集合更小,然后只考虑那个集合。

可能有更好的选择,但这是一个好的开始,我现在还没有足够的精力去解决更好的事情:(

【讨论】:

【参考方案2】:

您需要两个排序列表来模拟数据库对索引的操作,因为在排序列表中搜索内容非常快。

第一个列表应按From 属性排序,散列到第二个列表中,按To 属性排序。这类似于数据库的作用。

.Net 中的排序列表

.Net 有一个名为SortedList 的类可以进行键控和位置访问,您可以使用它来实现您想要的。

您可以使用带有IComparer 的构造函数,您可以使用它来指示SortedList 应该如何比较您的Restriction 类。您将需要编写两个 IComparers,一个用于比较 From 属性,另一个用于比较 To 属性。

【讨论】:

【参考方案3】:

如果您有很多查询但插入的次数不多,您可以执行以下操作: 创建两个排序的对象列表,一个按fromDate 排序,另一个按toDate 排序。然后,您可以在 sortedLists 上进行快速搜索,以查找每个列表、有效结果集(在第一个列表中查询带有 fromDate &lt;= searchDate 的条目,在第二个列表中查询 toDate &gt;= searchDate)。然后加入结果集得到结果。

【讨论】:

【参考方案4】:

此类问题的常见解决方案是实现分区;这是在数据库环境中实现的,以减少搜索空间。唯一需要注意的是,您的集合无法使用其他条件进行过滤,否则您需要建立索引。

示例实现可能会使用一组包含特定日期范围(按月、年等)的列表。当您执行插入时,您确定正确的列表并将您的项目放置在该列表中。执行搜索时,您可以轻松确定正确的列表或列表集,然后仅在这些列表中执行扫描。

但是,您还应该考虑这一点——您将处理多少个元素?只有当元素数量非常大时,扫描整个列表才会成为一个严重的问题。如果您不处理大量数据,那么优化这个问题还为时过早。

【讨论】:

以上是关于如何快速过滤满足日期范围条件的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中按日期范围过滤记录?

仅在满足另一个条件时如何按列过滤查询

Django:按日期范围过滤对象

使用 and:false 条件 SAPUI5 过滤日期范围的 Odata 服务值

具有特定条件计数的 Mongodb 聚合并按输出投影的日期范围过滤不能按预期工作

在 Django 中,如何优雅地将查询集过滤器添加到大型组或对象的所有成员?