全文搜索引擎的比较- Lucene, Sphinx, Postgresql, MySQL?

我正在建设一个Django网站,我正在寻找一个搜索引擎。

一些候选人:

  • Lucene/Lucene with Compass/Solr

  • 斯芬克斯

  • Postgresql内置全文搜索

  • MySQl内置全文搜索

选择标准:

  • 结果相关性和排名
  • 搜索和索引速度
  • 易于使用,易于与Django集成
  • 资源需求——站点将托管在VPS上,所以理想情况下搜索引擎不需要大量的RAM和CPU
  • 可伸缩性
  • 额外的功能,如“你的意思是?”,相关搜索等

任何使用过上述搜索引擎或其他不在列表中的引擎的人——我很想听听你的意见。

编辑:至于索引需求,由于用户不断地向站点输入数据,这些数据将需要不断地进行索引。它不必是实时的,但理想情况下,新数据在索引中显示的延迟不超过15 - 30分钟

154324 次浏览

我不了解Sphinx,但是对于Lucene和数据库全文搜索,我认为Lucene的性能是无与伦比的。不管你要搜索多少条记录,只要你正确地设置了Lucene索引,你应该能够在不到10毫秒的时间内完成几乎任何的搜索。

最大的障碍来了:就我个人而言,我认为在你的项目中集成Lucene不是容易。当然,设置它并不难,这样你就可以做一些基本的搜索,但如果你想充分利用它,获得最佳性能,那么你绝对需要一本关于Lucene的好书。

对于CPU &内存需求,在Lucene中执行搜索不会给CPU太多的任务,尽管索引你的数据是,尽管你不经常这样做(可能一天一两次),所以这不是一个很大的障碍。

它不能回答你所有的问题,但简而言之,如果你有大量的数据要搜索,并且你想要出色的性能,那么我认为Lucene绝对是一条出路。如果你没有那么多的数据要搜索,那么你也可以使用数据库全文搜索。在我的书中,设置MySQL全文搜索绝对更容易。

很高兴看到有人插话谈论Lucene——因为我对此一无所知。

而斯芬克斯,我很了解,所以看看我能不能帮上忙。

  • 结果相关性排名是默认的。如果您愿意,您可以设置自己的排序,并赋予特定字段更高的权重。
  • 索引速度非常快,因为它直接与数据库对话。任何缓慢都会来自复杂的SQL查询和未索引的外键以及其他类似的问题。我也从来没有发现在搜索过程中有任何迟缓。
  • 我是一个Rails的人,所以我不知道用Django实现它有多简单。不过,Sphinx源代码附带了一个Python API。
  • 搜索服务守护进程(searchd)的内存使用率非常低——你也可以对索引器进程使用的多少内存设置限制。
  • 可伸缩性是我的知识比较粗略的地方——但是将索引文件复制到多台机器上并运行几个搜索守护进程是很容易的。但我从其他人那里得到的总体印象是,它在高负载下非常好,所以在多台机器上扩展它不是需要处理的问题。
  • 它不支持“did-you-mean”等等,尽管这些可以用其他工具轻松完成。Sphinx通过使用字典来做词干,所以“驾驶”和“驾驶”(例如)在搜索中被认为是相同的。
  • 不过,Sphinx不允许对字段数据进行部分索引更新。常见的方法是使用所有最近的更改维护一个增量索引,并在每次更改后重新索引它(这些新结果会在一两秒钟内出现)。由于数据量很小,这可能需要几秒钟的时间。您仍然需要定期重新索引主数据集(尽管如何定期取决于您的数据的波动性-每天?每小时?)快速的索引速度使这一切都相当轻松。

我不知道如何适用于你的情况,但Evan Weaver比较了几个常见的Rails搜索选项 (Sphinx, Ferret (Lucene的Ruby端口)和Solr),运行一些基准测试。我想可能有用。

我还没有深入研究MySQL的全文搜索,但我知道它在速度和功能方面都无法与Sphinx、Lucene或Solr竞争。

我现在正在研究PostgreSQL全文搜索,它拥有现代搜索引擎的所有正确功能,非常好的扩展字符和多语言支持,与数据库中的文本字段很好地紧密集成。

但它没有用户友好的搜索操作符,如+或AND(使用&| !),我对它在他们的文档网站上的工作方式并不感到兴奋。虽然它在结果片段中有粗体匹配项,但匹配项的默认算法并不好。此外,如果你想索引rtf, PDF, MS Office,你必须找到并集成一个文件格式转换器。

OTOH,它比MySQL的文本搜索好多了,后者甚至不能索引三个字母或更少的单词。它是MediaWiki搜索的默认值,我真的认为它对最终用户没有好处:http://www.searchtools.com/analysis/mediawiki-search/

在我所见过的所有案例中,Lucene/Solr和Sphinx都非常出色。它们都是可靠的代码,并且在可用性方面有了显著的改进,所以这些工具都可以让搜索满足几乎所有人。

对于SHAILI - SOLR包括Lucene搜索代码库和组件,是一个很好的独立搜索引擎。

SearchTools-Avi说:“MySQL文本搜索,它甚至不能索引三个字母或更少的单词。”

至少 MySQL 5.0起,MySQL全文的最小字长是可调的。谷歌'mysql全文最小长度'简单的指令。

也就是说,MySQL全文文本有局限性:首先,一旦你达到一百万左右的记录,它就会变得很慢,……

我很惊讶没有更多关于Solr的信息。Solr与Sphinx非常相似,但具有更高级的功能(我没有使用过Sphinx,只是阅读过它)。

下面链接的答案详细介绍了一些关于Sphinx的事情,这也适用于Solr。 全文搜索引擎的比较- Lucene, Sphinx, Postgresql, MySQL? < / p >

Solr还提供了以下附加特性:

  1. 支持复制
  2. 多核(可以把它们看作具有自己的配置和索引的独立数据库)
  3. 布尔搜索
  4. 突出显示关键字(如果你有regex-fu,在应用程序代码中很容易做到;但是,为什么不让一个专门的工具为你做更好的工作呢?
  5. 通过XML或分隔文件更新索引
  6. 通过HTTP与搜索服务器通信(它甚至可以返回Json,原生PHP/Ruby/Python)
  7. PDF, Word文档索引
  8. 动态字段
  9. 方面
  10. 聚合领域
  11. 停止单词、同义词等。
  12. 更像这样…
  13. 使用自定义查询直接从数据库中建立索引
  14. 缓存来自
  15. 快速索引(与MySQL全文搜索索引时间相比)——Lucene使用二进制倒排索引格式。
  16. 增强(用于增加特定关键字或短语相关性的自定义规则等)
  17. 字段搜索(如果搜索用户知道他/她想要搜索的字段,他们会通过输入字段,然后输入值来缩小搜索范围,并且只搜索该字段而不是所有内容——更好的用户体验)

顺便说一下,还有很多功能;但是,我只列出了在生产中实际使用的特性。顺便说一句,MySQL支持上述列表中的#1、#3和#11(有限)。对于您正在寻找的特性,关系数据库并不能满足您的需求。我会马上消除这些。

另外,Solr(实际上是Lucene)是一个文档数据库(例如NoSQL),因此任何其他文档数据库的许多优点都可以通过Solr实现。换句话说,您可以将它用于不仅仅是搜索(即性能)。要有创意:)

我会将mnoGoSearch添加到列表中。非常高性能和灵活的解决方案,它作为谷歌:索引器从多个站点获取数据,您可以使用基本标准,或发明自己的钩子,以获得最大的搜索质量。它还可以直接从数据库中获取数据。

这个解决方案今天还不太为人所知,但它满足了最大的需求。你可以编译并安装它,或者在独立的服务器上,甚至在你的主服务器上,它不需要像Solr那样多的资源,因为它是用C编写的,即使在小型服务器上也能完美运行。

一开始你需要自己编译,所以需要一些知识。我为Debian做了一个微小的脚本,这可能会有帮助。欢迎任何调整。

由于您使用的是Django框架,您可以使用或PHP客户端在中间,或在Python中找到解决方案,我看到一些 文章

当然,mnoGoSearch是开源的,GNU GPL。

这是我对这个老问题的看法。我强烈建议你看一下ElasticSearch

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式的、支持多租户的全文搜索引擎,具有RESTful web界面和无模式的JSON文档。Elasticsearch是用Java开发的,在Apache许可证的条款下作为开源发布。

相对于其他FTS(全文搜索)引擎的优势是:

  • rest式接口
  • 更好的可伸缩性
  • 大型社区
  • 由Lucene构建 开发人员李< / >
  • 丰富的文档
  • 有很多可用的开源库(包括Django)

我们在我们的项目中使用这个搜索引擎,并且非常满意。

Apache Solr


除了回答OP的问题,让我抛出一些关于Apache Solr < em > < / em >简单介绍详细的安装实现的见解。

简单介绍


任何使用过上述搜索引擎或其他搜索引擎的人 我想听听你的意见。

Solr不应该用来解决实时问题。对于搜索引擎,Solr几乎是游戏,工作于完美无瑕地

Solr在高流量web应用程序(我在某处读到,它不适合这个,但我支持这种说法)上工作正常。它利用的是RAM,而不是CPU。

  • 结果相关性和排名

提高帮助你把你的结果排在最上面。比方说,你试图在firstname字段中搜索一个名字约翰,并且你想给firstname字段赋予相关性,那么你需要提高向上firstname字段,如图所示。

http://localhost:8983/solr/collection1/select?q=firstname:john^2&lastname:john

如你所见,firstname字段是提高了向上,分数为2。

更多关于SolrRelevancy

  • 搜索和索引速度

速度快得令人难以置信,在这一点上没有妥协。我搬到Solr的原因。

关于索引速度,Solr也可以处理数据库表中的连接。更高更复杂的加入确实会影响索引速度。然而,一个庞大的内存配置可以很容易地解决这种情况。

RAM越大,Solr的索引速度越快。

  • 易于使用,易于与Django集成

从未尝试集成SolrDjango,但是您可以通过干草堆实现这一点。我发现一些有趣的文章相同,这里是它的github

  • 资源需求——站点将托管在VPS上,所以理想情况下搜索引擎不需要大量的RAM和CPU

Solr在RAM上繁殖,所以如果RAM很高,你不必担心Solr

Solr的内存使用在全索引时激增,如果你有十亿条记录,你可以聪明地使用Delta导入来解决这种情况。如上所述,Solr 只是一个接近实时的解决方案吗

  • 可伸缩性

Solr是高度可伸缩的。看看SolrCloud

  • 碎片(或者分片是在多台机器上分配索引的概念,比如如果您的索引变得太大)
  • 负载平衡(如果Solrj与Solr云一起使用,它会自动使用它的轮询机制来处理负载平衡)
  • 分布式搜索 .
  • 高可用性
  • 额外的功能,如“你的意思是?”,相关搜索等

对于上面的场景,你可以使用SpellCheckComponent,它与Solr打包在一起。还有很多其他特性,SnowballPorterFilterFactory帮助检索记录,如果你输入而不是,你将显示与相关的结果。


这个答案主要集中在Apache Solr &MySQL。Django超出了范围。

假设您在LINUX环境下,您可以继续阅读本文。(我用的是Ubuntu 14.04版本)

详细的安装

开始

在这里下载Apache Solr。也就是version is 4.8.1。你可以下载新版本,我觉得这个很稳定。

下载存档后,将其解压缩到您选择的文件夹中。 说. .Downloads或其他…所以它看起来像Downloads/solr-4.8.1/

听你的提示…在目录内导航

shankar@shankar-lenovo: cd Downloads/solr-4.8.1

所以现在你在这里…

shankar@shankar-lenovo: ~/Downloads/solr-4.8.1$

启动Jetty应用程序服务器

码头solr-4.8.1目录的examples文件夹中可用,因此在该目录中导航并启动Jetty应用程序服务器。

shankar@shankar-lenovo:~/Downloads/solr-4.8.1/example$ java -jar start.jar

现在,不要关闭终端,最小化它,让它留在一边。

(提示:使用&使Jetty Server在。jar中运行 背景)< / p >

要检查Apache Solr是否成功运行,请在浏览器上访问此URL。http://localhost:8983/solr

在自定义端口上运行Jetty

它默认运行在8983端口上。你可以在这里或直接在jetty.xml文件中更改端口。

java -Djetty.port=9091 -jar start.jar

下载JConnector

这个JAR文件充当MySQL和JDBC之间的桥梁,下载平台独立版本在这里

下载后,解压文件夹并复制__abc0并将其粘贴到自由目录。

shankar@shankar-lenovo:~/Downloads/solr-4.8.1/contrib/dataimporthandler/lib

创建要链接到Apache Solr的MySQL表

要使用Solr,你需要有一些表和数据来搜索。为此,我们将使用MySQL创建一个表并推送一些随机名称,然后我们可以使用Solr连接到MySQL并索引该表及其条目。

1.表结构

CREATE TABLE test_solr_mysql
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NULL,
created TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);

2.填充上面的表

INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jean');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jack');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jason');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Vego');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Grunt');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jasper');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Fred');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Jenna');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Rebecca');
INSERT INTO `test_solr_mysql` (`name`) VALUES ('Roland');

进入核心并添加lib指令

1.导航到

shankar@shankar-lenovo: ~/Downloads/solr-4.8.1/example/solr/collection1/conf

2.修改“solrconfig.xml”文件

将这两个指令添加到这个文件中。

  <lib dir="../../../contrib/dataimporthandler/lib/" regex=".*\.jar" />
<lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />

现在添加DIH(数据导入处理程序)

<requestHandler name="/dataimport"
class="org.apache.solr.handler.dataimport.DataImportHandler" >
<lst name="defaults">
<str name="config">db-data-config.xml</str>
</lst>
</requestHandler>

3.创建db-data-config.xml文件

如果文件存在,则忽略,将这些行添加到该文件中。正如你看到的第一行,你需要提供你的MySQL数据库的凭据。数据库名、用户名和密码。

<dataConfig>
<dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/yourdbname" user="dbuser" password="dbpass"/>
<document>
<entity name="test_solr" query="select CONCAT('test_solr-',id) as rid,name from test_solr_mysql WHERE '${dataimporter.request.clean}' != 'false'
OR `created` > '${dataimporter.last_index_time}'" >
<field name="id" column="rid" />
<field name="solr_name" column="name" />
</entity>
</document>
</dataConfig>

(提示:你可以有任何数量的实体,但要注意id字段, 如果它们是相同的,那么索引将被跳过。)< / p >

4.修改schema.xml文件

将此添加到你的schema.xml中,如下所示..

<uniqueKey>id</uniqueKey>
<field name="solr_name" type="string" indexed="true" stored="true" />

实现

索引

这才是真正的交易。为了使用Solr查询,你需要将数据从MySQL索引到Solr

步骤1:进入Solr管理面板

在浏览器上点击URL http://localhost:8983/solr。屏幕像这样打开。

This is main Apache Solr Administration Panel

如标记所示,转到日志记录以检查上述配置是否导致错误。

步骤2:检查日志

好的,现在你在这里,正如你所能看到的,有很多黄色的信息(警告)。确保没有用红色标记的错误消息。之前,在我们的配置中,我们在db-data-config.xml上添加了一个选择查询,如果该查询上有任何错误,它就会显示在这里。

This is the logging section of your Apache Solr engine

很好,没有错误。我们准备好了。让我们从列表中选择文物并选择Dataimport

步骤3:DIH(数据导入处理程序)

使用DIH,你将从Solr通过配置文件db-data-config.xmlSolr接口连接到MySQL,并从索引到Solr的数据库中检索10条记录。

要做到这一点,选择full-import,并检查选项清洁提交。现在,如图所示单击执行

或者,你也可以像这样直接使用full-import查询。

http://localhost:8983/solr/collection1/dataimport?command=full-import&commit=true

数据导入处理程序

在你点击执行之后,Solr开始索引记录,如果有任何错误,它会说索引失败,你必须回到日志记录部分,看看哪里出了问题。

假设此配置没有错误,且索引已成功完成。,你会收到这个通知。

Indexing Success

步骤4:运行Solr查询

看起来一切都很顺利,现在你可以使用Solr Queries来查询被索引的数据了。点击左边的查询,然后按下底部的执行按钮。

您将看到索引记录,如所示。

对应的列出所有记录的Solr查询是

http://localhost:8983/solr/collection1/select?q=*:*&wt=json&indent=true

索引数据

好了,这就是所有10条索引记录。比如说,我们只需要以晶澳开头的名称,在这种情况下,你需要以列名solr_name为目标,因此你的查询是这样的。

http://localhost:8983/solr/collection1/select?q=solr_name:Ja*&wt=json&indent=true

以Ja*开头的JSON数据

这就是Solr Queries的编写方法。要了解更多信息,请查看这个美丽的文章

我们刚刚从Elasticsearch切换到Postgres全文。因为我们已经使用了Postgres,所以我们现在省去了保持索引更新的麻烦。 但这只影响全文搜索。然而,在某些用例中,Elasicsearch明显更好。可能是facet或类似的东西