【问题标题】:Storing search result for paging and sorting存储用于分页和排序的搜索结果
【发布时间】:2011-01-17 02:42:47
【问题描述】:

我一直在实施 MS Search Server 2010,到目前为止它非常好。我通过他们的网络服务进行搜索查询,但由于 results 不一致,我正在考虑缓存结果。

该站点是一个小型 Intranet(500 名员工),因此应该不会有任何问题,但我很好奇如果它是一个更大的站点,您会采取什么方法。

我用谷歌搜索了一下,但还没有真正找到任何具体的东西。所以,有几个问题:

  • 还有哪些其他方法?为什么它们更好?
  • 存储 400-500 行的数据视图需要多少成本?什么尺寸是可行的?
  • 您应该考虑的其他几点。

欢迎任何意见:)

【问题讨论】:

  • 你看过 Apache SOLR 吗?

标签: c# asp.net search search-engine


【解决方案1】:

您需要采用多种技术才能成功实现这一目标。

首先,您需要某种持久层。如果您使用的是普通的旧网站,那么用户的会话将是最合乎逻辑的层。如果您正在使用 Web 服务(意味着无会话)并且只是通过客户端进行调用,那么您仍然需要某种应用程序层(某种共享会话)来提供服务。为什么?该层将是您的数据库结果缓存的所在地。

第二,您需要一种将结果缓存在您使用的任何容器(会话或 Web 服务的应用层)中的方法。您可以通过多种方式执行此操作...如果查询是任何用户都可以执行的操作,则查询的简单哈希将起作用,并且您可以在其他用户之间共享此存储的结果。您可能仍然需要某种形式的 GUID 作为结果,以便您可以在客户端应用程序中传递它,但是从查询到结果的哈希查找将很有用。如果这些查询是唯一的,那么您可以将唯一的 GUID 用于查询结果并将其传递给客户端应用程序。这样您就可以执行缓存功能...

缓存机制可以包含某种固定长度的缓冲区或队列...以便在添加新结果时自动清除/删除旧结果。然后,如果有一个缓存未命中的查询进入,它将正常执行并添加到缓存中。

第三,您将需要某种方式来分页您的结果对象......迭代器模式在这里工作得很好,虽然可能更简单的东西可能工作......比如 fetch X 从点 Y 开始的结果数量。但是,迭代器模式会更好,因为您可以稍后删除缓存机制,如果您愿意,可以直接从数据库中分页。

第四,您需要某种预取机制(正如其他人所建议的那样)。您应该启动一个可以进行完整搜索的线程,并在您的主线程中快速搜索前 X 个项目。希望当用户尝试分页时,第二个线程将完成,您的完整结果现在将在缓存中。如果结果还没有准备好,你可以加入一些简单的加载屏幕逻辑。

这应该可以帮助您...让我知道您是否需要有关任何特定部分的说明/更多详细信息。

我会给你一些提示......

  1. 您不想将整个结果发送到客户端应用程序(如果您使用 Ajax 或类似 iPhone 应用程序)。为什么?好吧,因为那是一个巨大的浪费。用户可能不会翻阅所有结果...现在您只是发送了超过 2MB 的结果字段。

  2. Javascript 是一门很棒的语言,但请记住,它仍然是一种客户端脚本语言……您不希望通过发送大量数据供 Ajax 客户端处理而大大降低用户体验.只需将预取的结果发送给您的客户端,并将其他页面结果作为用户页面发送。

  3. Abstraction 抽象抽象...您想抽象出缓存、查询、分页、预取...尽可能多的抽象。为什么?好吧,假设您想切换数据库,或者您想直接从数据库中分页,而不是使用缓存中的结果对象……好吧,如果您做得对,以后更改会容易得多。此外,如果使用 Web 服务,许多其他应用程序可以在以后使用此逻辑。

现在,我可能针对您的需要提出了一个过度设计的解决方案 :)。但是,如果您可以使用所有正确的技术来实现这一目标,那么您将学到很多东西并拥有非常好的基础,以防您想要扩展功能或重用此代码。

如果您有任何问题,请告诉我。

【讨论】:

  • 我忘了回答。对不起。我确实将缓存用于 Web 服务调用和会话用于 Web 服务器搜索。感谢您的广泛回答,真的很有帮助!
【解决方案2】:

听起来搜索的缓慢部分是全文搜索,而不是结果检索。缓存生成的资源记录 ID 怎么样?此外,由于搜索查询经常重复,因此存储搜索查询、查询和匹配资源的哈希值。然后您可以按 ID 检索下一页结果。也适用于 AJAX。

由于它是一个 Intranet,并且您可以控制搜索的资源,您甚至可以在空闲时间预先计算新的或更新的资源与热门查询的匹配。

【讨论】:

    【解决方案3】:

    如果您能够在第二个线程中运行初始查询并且要应用于结果的逻辑(分页/排序/过滤)需要在服务器上执行操作,那么 Tim 的回答是处理事情的好方法...... ..否则..

    如果您可以使用 AJAX,则可以将 500 行的结果集调用到页面中并在客户端上进行分页或排序。这可以带来一些非常有趣的功能....查看来自 jQueryUI 和 Dojo 的数据网格解决方案以获得灵感!

    对于诸如任意正则表达式过滤器和拖放列重新排序等真正密集的功能,您可以完全释放服务器。

    同时将数据全部加载到浏览器还可以让您在用户“请求”它们时调用支持数据(页面预览等)......

    主要问题是将每个结果返回的数据限制为实际用于排序和过滤器的数据。

    可能性是无限的:)

    【讨论】:

    • 但希望您的搜索算法能早日带来好的结果,这样您就会不必要地加载 490 个结果和页面预览图像
    【解决方案4】:

    我不得不承认我对 MS Search Server 不是很熟悉,所以这可能不适用。我经常遇到这样的情况,即应用程序必须在数亿条记录中搜索需要在 SQL Server 中排序、分页和子搜索的结果集。通常我所做的是采取两步法。首先,我抓取需要显示的第一个“x”结果并将它们发送到浏览器以便快速显示。其次,在另一个线程上,我完成了完整的查询并将结果移动到一个临时表中,在那里可以更快地存储和检索它们。任何给定的查询可能有成千上万的结果,但与数亿甚至数十亿的总记录相比,这个较小的子集可以很容易地从临时表中操作。随着查询的发生,它还减轻了对其他表的压力。如果用户需要第二页记录,或者需要对它们进行排序,或者只是想要原始查询的一个子集,这一切都是从临时表中提取的。

    然后需要实施逻辑来检查过时的临时表并将其删除。这很简单,我让 SQL Server 处理该功能。最后,必须为原始查询更改(显着的周界更改)设置逻辑,以便可以提取新数据集并将其放入新的临时表中以进行进一步查询。所有这些都比较简单。

    用户习惯于将第二次返回时间从谷歌之类的地方分开,这个模型给了我足够的灵活性来实际实现这一点,而不需要他们使用的专门的软件和硬件。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多