存储搜索结果以进行分页和排序

时间:2010-02-15 18:47:14

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

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

该网站是一个小型内联网(500名员工),所以它不应该是任何问题,但我很好奇如果它是一个更大的网站你会采取什么方法。

我已经google了abit,但还没有真正解决任何具体问题。所以,有几个问题:

  • 还有其他方法吗?为什么他们会更好?
  • 存储400-500行的数据视图需要多少费用?什么尺寸可行?
  • 您应该考虑的其他方面。

欢迎任何输入:)

4 个答案:

答案 0 :(得分:2)

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

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

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

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

第三次,你会想要一些方法来分页你的结果对象...... Iterator模式在这里工作得很好,虽然可能更简单的东西可能有效...就像获取 X < / strong>从 Y 点开始的结果量。但是Iterator模式会更好,因为您可以在以后删除缓存机制并直接从数据库中页面,如果您愿意的话。

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

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

我会留下更多提示......

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

  2. Javascript是一种非常棒的语言,但请记住它仍然是一种客户端脚本语言...您不希望通过为Ajax客户端发送大量数据来减慢用户体验。只需将客户端和其他页面结果的预取结果作为用户页面发送。

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

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

    如果您有疑问,请告诉我。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

然后需要建立逻辑来检查过时的临时表并将其删除。这很简单,我让SQL Server处理该功能。最后,必须在原始查询发生变化(显着的周长变化)时建立逻辑,以便可以拉出新数据集并将其放入新的临时表中以进一步查询。所有这些都相对简单。

用户习惯于从谷歌这样的地方分割第二次返回时间,这种模式为我提供了足够的灵活性来实现这一目标,而无需使用他们使用的专用软件和硬件。

希望这有点帮助。

答案 3 :(得分:0)

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

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

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

一旦将数据加载到浏览器中,您也可以在用户“请求”它们时调用支持数据(页面预览等)....

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

可能性无穷无尽:)