0

我不想使用 Lucene,因为我认为它太重了

有没有更简单的方法来实现这个(数百万数据)?

4

3 回答 3

0

首先,对于自动完成,如果您想要快速显示的内容,您的目标应该是在 <= 100 毫秒内将响应返回给用户。这应该是您首先关心的问题。任何无法做到这一点的设置可能对用户来说都不够好。在我自己使用 Firebug 在 Firefox 中进行的测试中,Google 的自动完成在大约 50 毫秒内返回返回,Quora 在大约 65 毫秒内返回。

见,例如

http://stackoverflow.com/questions/536300/what-is-the-shortest-perceivable-application-response-delay

显然,Quora 使用前缀匹配,而不是全文搜索,这使得它更快。要推出您自己的基于前缀的快速自动完成功能,这对于许多情况来说应该足够了,但不会使用模糊匹配处理拼写错误等问题,请尝试使用 Redis 等内存数据存储。详细信息可以在这里看到:

http://charlesleifer.com/blog/powerful-autocomplete-with-redis-in-under-200-lines-of-python/

我无法让 CloudSearch(浏览器中直接从端点获取 95-125 毫秒,由 Firebug 测量,并且通过 PHP 中的 cURL 访问端点的时间延长 20-30 毫秒)降低到我引用的谷歌和 Quora 的低延迟,无论搜索查询的简单性。Elasticsearch 集群要快一些。这些陈述显然取决于用例,可能不能很好地概括,但需要考虑一些事情。

于 2013-09-11T04:21:45.383 回答
0

如果您不想担心性能,我建议您看看 Amazon Web Services 新的 CloudSearch 服务。它速度很快,并且可以随着您的需求扩展而扩展。它还可以毫无问题地处理数百万个文档并支持通配符搜索(例如:quo*,将检索 Quora)。

在这里查看。

于 2012-09-23T15:19:01.630 回答
0

显然,这不是 Quora 或 Google 的工作方式,因为我没有在任何一个工作过的乐趣......这就是我要做的事情。

首先要获得的是搜索词列表 - 我假设您不想知道这是如何完成的,因为它实际上取决于各种各样的事情,但基本上您要么要做一个select distinct title from pages(在维基百科上的自动完成的情况下)或在谷歌的情况下更先进的东西。

下一步在高层次上也非常简单:您需要select title from titles where title like 'Qu%'在用户输入Qu搜索框的情况下执行查询。然后将标题列表作为对某种 Ajax 请求的响应返回给浏览器,可能是 JSON 或类似的形式。你需要尽可能快地完成它——这就是它变得困难的地方。

他们怎么做的这么快?大概有四点需要注意。

  1. 他们有很多机器处理请求。请记住,Google 的自动完成功能在默认情况下是打开的,并且适用于(几乎?)所有语言。这是针对自动完成索引的大量搜索。对网络索引本身的影响远不止于此:对于每个网络搜索请求,Google 可能已经处理了 3 或 4 个自动完成请求。
  2. 他们可能是在记忆中这样做的。众所周知,谷歌将其网络索引存储在内存中,所以我希望他们也会这样做。
  3. 专业软件(这是它真正有趣的地方)。虽然传统数据库或 NoSQL 数据库可以做到这一点并快速完成,但我希望大男孩们实际上会使用专门的代码来做到这一点,其唯一目的是提供自动完成建议。我上面提供的 SQL 语句纯粹是为了演示所需的逻辑请求。您可能正在查看某种专门的树,例如后缀树、基数树或类似树。
  4. 分片。为了应对数据量和执行请求的机器数量,您需要进行分片。这是确保所涉及的所有机器的某个子集仅处理以一个或多个字母开头的请求请求。例如,一组 X 机器处理以某个字母或什至 2 个字母开头的搜索。这意味着你有更多的机器,但它们并不都必须手头有整个索引。如何选择一组特定的机器?一旦请求在您的数据中心,您要么路由,要么您可以在客户端路由(例如,在您的 Javascript 中,根据搜索词的前 X 个字母决定要查询的 IP)

所以,我就是这样做的。由于没有经历过 Google/Quora 处理的庞大数据集,我敢肯定有些事情我没有考虑过。但是,这是一个开始。

而且,我是这样做的,纯粹是在家里的实验环境中:

我有一个简单的列表,里面有几十万个标题要搜索。这些被加载到一个专用的 MongoDB 集合中,该集合上定义了一个索引。然后我在它前面有一个 Play Framework 控制器,并使用 jQuery 的自动完成插件来进行搜索。

显然,与您正在寻找的相比,这很小,但只要您遵循建议(即良好的硬件、大量的 RAM、将索引保存在内存中),MongoDB 应该为您的数据集提供相同的性能。此外,Mongo 支持分片,并且 Play 框架不共享任何内容,因此在这种情况下,如果您的用户群增长,添加新机器以应对负载将很简单。

顺便说一句,Mongo 绝不是唯一的解决方案,当然,传统的 SQL 数据库也可以胜任——我只是出于其他原因使用 Mongo。

于 2012-09-24T11:42:53.347 回答