【问题标题】:How to create autosuggest to get keywords as fast as google search or live search如何创建自动建议以像谷歌搜索或实时搜索一样快速获取关键字
【发布时间】:2010-10-20 22:38:37
【问题描述】:

我正在我的网站搜索框中创建自动建议功能,每次用户按下新键时,javascript 都会在服务器端调用 web 服务以从数据库中获取 10 个最相关的关键字并再次提供给 javascript,然后 javascript填充搜索自动建议列表。

我的功能并不算太慢,但与 live.com 或 google.com 的速度相比,我对它们进行了测试,我真的觉得他们是从我的电脑而不是从他们的服务器获取关键字。

他们如何如此快速地获得关键字,并确保他们拥有数百万倍于我的关键字?
有这样出名的风格吗?
同样使用我的萤火虫,我发现他们没有调用网络服务“可能以我不知道的方式调用”,但我在“网络”选项卡中发现正在发生新的获取。

【问题讨论】:

  • 1) 他们有更多的带宽。 2)他们有更多的服务器 3)。在搜索并获取整页结果时,无论如何您都会获得亚秒级的结果,因此 10 个 js 列表很可能会更快。

标签: asp.net javascript autocomplete


【解决方案1】:

不确定你在看哪里,但肯定是在 live.com 上我收到了每封信的请求:

如您所见,通过网络返回的数据非常少 - 500B - 这就是您的目标 - 一个精简的 Web 服务,它返回您显示给用户所需的最小值。

然后最重要的是,正如其他人所说,缓存以前的响应等。

并不是说结果通常不按字母顺序排列,因此如果您不显示您的排序标准,您可以按照“现在总比以后完全准确”的原则工作。

【讨论】:

    【解决方案2】:

    与其每次按键都发出请求,不如在中间有按键的情况下每隔一定时间发出一个请求怎么办?如果您执行类似 100 毫秒间隔的操作,它看起来仍然是“即时的”,但您的服务器上的负载可能会少得多。另外,您是否让客户端缓存关键字?如果用户在搜索字段中退格,则不必重新联系服务器以获取关键字。此外,您可以立即过滤每个按键上的当前关键字列表,而无需联系服务器(您最终会得到少于 10 个关键字,因为您已经拥有的部分/全部不包含刚刚输入的字母)。这可以填补实际数据请求之间的“空白”,使其看起来更即时。

    【讨论】:

    • 你能再解释一下“每隔一定时间提出一个请求”的想法吗?,缝合一些聪明的东西,但我觉得我不能完美地理解它。
    • 这个想法是将请求限制为最多每 100 毫秒。在伪代码中,而不是“on_keypress:发出请求”,执行如下操作:“on_keypress:如果计时器正在运行,则返回。否则将计时器设置为从现在开始 100 毫秒发出请求”。计时器发出的请求应该使用用户当时输入的任何内容,而不是用户在计时器启动时输入的内容(不确定如何在 JS 中执行此操作,因为它可能是线程的事情)。
    【解决方案3】:

    没有理由在每次按键时都请求搜索字词。 Google 这样做 (1) 是因为他们可以,并且 (2) 因为他们在整个互联网语料库中呈现术语。

    在大多数网络应用程序中,“常用”搜索词的数量要少得多——通常不超过一百个左右,而适合上下文的则少至十几个。

    您可以在页面加载时检索整个相关术语集并在客户端构建前缀映射。通过将当前搜索词与此前缀映射匹配,您可以比 Google 更快地提供建议。

    限制是,在某些时候,您会用完建议的术语。但同样,这真的不是问题:即使是谷歌也没有关于“transnormative”(一个虚构的词,但完整搜索有 191 个结果)的建议。

    【讨论】:

      【解决方案4】:

      您可以做两件主要的事情:

      1. 在服务器端使用尽可能多的缓存。毕竟,搜索查询遵循幂律。有很多请求的查询很少,每个请求很少的很多查询。完美的缓存环境
      2. 您需要尽量减少传输的数据量,一种方法是使用radix tree。如果您需要传输一个包含 20 个字符串的列表,所有这些字符串都共享一个公共前缀,那么您不需要传输 20 个单独的字符串。您可以传输一次前缀,然后传输 20 个不同的部分。

      【讨论】:

        【解决方案5】:

        我建议的第一件事是确保您的 Web 服务将它们的关键字缓存在内存中,而不是每次都访问数据库 - 当然假设您的数据集足够小来执行此操作。

        除此之外,您还必须以某种方式跨多个服务器并行化查询,这可能比您想要的复杂得多。

        【讨论】:

          【解决方案6】:

          找到了这篇博文,在这一点上有详细的讨论:

          Autocomplete Data Structures

          【讨论】:

            【解决方案7】:

            首先,您应该重新表述您的问题。任何“我怎么能像谷歌一样快”的答案都注定是“习惯失望”。

            鉴于此,您仍然可以改进您的解决方案。似乎每次按键,您都会往返于服务和数据库。我怀疑谷歌会这样做。也许您应该专注于减少往返次数(cahcing,当您必须去数据库时带回更多,等等)。

            【讨论】:

              【解决方案8】:

              正如上面有人建议的那样,使用 ETags 和 REST api 可能意味着对重复查询进行一些额外的缓存。查看 Jeo Gregorio 博客上的 this 文章,了解 REST 上下文中的更多信息 etag。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-02-22
                • 1970-01-01
                • 2013-05-02
                • 2012-11-10
                • 2014-08-26
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多