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


312

我正在建立Django网站,并且正在寻找搜索引擎。

一些候选人:

  • Lucene / Lucene与指南针/ Solr

  • 狮身人面像

  • Postgresql内置全文本搜索

  • MySQl内置全文本搜索

选择标准:

  • 结果相关性和排名
  • 搜索和索引速度
  • 易于使用,易于与Django集成
  • 资源需求-网站将托管在VPS上,因此理想情况下,搜索引擎不需要大量的RAM和CPU
  • 可扩展性
  • 其他功能,例如“您的意思是?”,相关搜索等

任何对以上搜索引擎或其他不在列表中的引擎有经验的人-我很想听听您的意见。

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


26
2分:(目前)MySQL全文搜索和事务是互斥的。MySQL全文索引需要MyISAM表类型,该表类型不支持事务。(与支持事务但不支持全文索引的InnoDB表类型相反。)
Carl G 2010年

2
PostgreSQL全文搜索,Tsearch 支持短语搜索。但是,它在TODO列表上sai.msu.su/~megera/wiki/FTS_Todo
迦南姆2010年

1
使用Django的人都应该签出haystack应用程序。haystacksearch.org
Keyo


24
@CarlG,仅供大家参考。MySQL 5.6+具有innodb引擎的全文本搜索支持
DhruvPathak

Answers:


167

很高兴看到有人对Lucene情有独钟-因为我对此一无所知。

另一方面,狮身人面像我很了解,所以让我们看看我是否可以帮上忙。

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

我不知道这对您的情况有多适用,但是Evan Weaver比较了一些常见的Rails搜索选项(Sphinx,Ferret(Ruby的Lucene移植版)和Solr),并运行了一些基准测试。我猜可能会有用。

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


Sphinx确实允许您更新当前索引中项目的各个属性,但不能删除/更新完整记录。
Xorlev

sphinx RT允许您进行部分更新/删除。它处于早期阶段,但已经[几乎]有效。sphinxsearch.com/wiki/doku.php?id=rt_tutorial
pQd

4
这是Solr的一个答案,与Sphinx的这个答案很不错
New Alexandria

没有什么比Sphinx的速度更好,因此,如果速度是您最关心的问题,那么Sphinx是您追求的选择。不错的帖子
twigg '17

Sphinx 2.3.2 Beta现在具有一个名为“ CALL SUGGEST”的功能,可用于实现“您的意思是?”。sphinxsearch.com/docs/devel.html#sphinxql-call-suggest
Vinod K,

82

我不知道Sphinx,但是对于Lucene与数据库全文搜索,我认为Lucene的性能无与伦比。只要您已正确设置Lucene索引,无论您要搜索多少记录,您都应该能够在10毫秒内完成几乎所有搜索。

不过,这是最大的障碍:就个人而言,我认为将Lucene集成到您的项目中并不容易。当然,对其进行设置并不是很困难,因此您可以进行一些基本搜索,但是如果您想充分利用它并以最佳性能进行搜索,那么您肯定需要一本有关Lucene的好书。

至于CPU和RAM的需求,尽管对数据进行索引是很重要的,但是在Lucene中执行搜索并不会给您的CPU带来太多的负担,尽管您这样做的频率不是很高(一天一次或两次),所以这并不是很大的障碍。

它并不能回答您所有的问题,但是总之,如果您要搜索大量数据,并且希望获得出色的性能,那么我认为Lucene无疑是必经之路。如果您不需要搜索那么多数据,那么您最好进行数据库全文搜索。在我的书中,设置MySQL全文搜索绝对容易。


10
与狮身人面像相比,Lucence太慢且笨重。我在项目中都使用过,最后我坚持使用了狮身人面像。Lucence在Java中,比Sphinx需要更多的CPU和RAM。
Phyo Arkar Lwin 2011年

25
我不得不在这里不同意。如果您建立正确的索引,Lucene将会很快。您基本上可以在几毫秒内对数百万条记录进行高级查询。您只需要知道自己在做什么。Lucene在Java中...您的意思是?还有.NET端口,Lucene.NET btw。
拉齐

15
但您明确声明您不使用狮身人面像,而v3sson都使用了两者。
user508546 2012年

20
如何用未声明使用狮身人面像的同一句话来说明lucene的性能无与伦比?
user508546 2012年

22
有效问题。我从来没有说过Lucene比Sphinx快,我曾提到Lucene与数据库全文搜索是无与伦比的。是的。毫无疑问。Lucene基于倒排索引。现在我不知道Sphinx,如前所述,但是如果它还使用倒排索引或类似的索引方法,则它们可能表现相同。指出与Sphinx相比,Lucene会“太慢且笨重”,这并非基于事实。特别是当只说Lucene在“ Java”中时,并不是这样,就性能而言,这只是一个荒谬的问题。
拉齐

60

我很惊讶没有发布更多有关Solr的信息。Solr与Sphinx非常相似,但具有更高级的功能(AFAIK,因为我没有使用Sphinx-只阅读了它)。

下面的链接上的答案详细介绍了有关Sphinx的一些内容,这些内容也适用于Solr。 全文搜索引擎的比较-Lucene,Sphinx,Postgresql,MySQL?

Solr还提供以下附加功能:

  1. 支持复制
  2. 多核(将它们视为具有各自配置和索引的独立数据库)
  3. 布尔搜索
  4. 突出显示关键字(如果有正则表达式,则在应用程序代码中很容易做到;但是,为什么不让专业工具为您做得更好呢?)
  5. 通过XML或分隔文件更新索引
  6. 通过HTTP与搜索服务器通信(它甚至可以返回Json,本机PHP / Ruby / Python)
  7. PDF,Word文档索引
  8. 动态场
  9. 刻面
  10. 汇总字段
  11. 停用词,同义词等
  12. 像这样...
  13. 使用自定义查询直接从数据库建立索引
  14. 自动建议
  15. 缓存自动预热
  16. 快速索引编制(与MySQL全文搜索索引编制时间相比)-Lucene使用二进制反向索引格式。
  17. 提升(用于增加特定关键字或词组等的相关性的自定义规则)
  18. 字段搜索(如果搜索用户知道他/她想要搜索的字段,他们将通过键入字段,然后输入值来缩小搜索范围,并且仅搜索该字段而不是搜索所有字段,这将带来更好的用户体验)

顺便说一句,还有更多的功能;但是,我只列出了生产中实际使用的功能。顺便说一句,MySQL开箱即用地支持上面列表中的#1,#3和#11(受限制)。对于您要寻找的功能,关系数据库不会削减它。我会马上消除这些。

另外,另一个好处是Solr(实际上是Lucene)是一个文档数据库(例如NoSQL),因此,任何其他文档数据库的许多好处都可以通过Solr来实现。换句话说,您不仅可以将其用于搜索(即“效果”),还可以将其用于其他目的。发挥创意:)


Sphinx也支持复制多核布尔搜索关键字突出显示通过XML更新索引-或分隔文件-PDF,Word文档索引(通过xml)方面停止单词,同义词等。使用自定义查询直接从数据库索引自动建议快速索引增强字段搜索关于动态字段聚合字段缓存自动变暖我只是不知道
Moosh 2013年

58

阿帕奇· 索尔( Apache Solr)


除了回答OP的查询之外,让我从简单的介绍详细的安装实现,Apache Solr进行一些分析。

简单介绍


任何对以上搜索引擎或其他不在列表中的引擎有经验的人-我很想听听您的意见。

Solr不应用于解决实时问题。对于搜索引擎而言,Solr几乎是一款游戏,并且可以完美运行

Solr在“高流量” Web应用程序上运行良好(我在某处读到它不适合此操作,但我正在备份该声明)。它利用RAM,而不是CPU。

  • 结果相关性和排名

升压帮助你的排名结果中显示在上面。我说,你想搜索的名字约翰在田里名字姓氏,以及你想给相关的姓名字段,那么你需要提高名字字段,如图所示。

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

如您所见,名字字段的得分提高了2。

有关Solr相关性的更多信息

  • 搜索和索引速度

速度之快令人难以置信,并且对此毫不妥协。我之所以搬到Solr的原因。

关于索引速度,Solr还可以处理数据库表中的JOINS。较高且复杂的JOIN确实会影响索引编制速度。但是,巨大的RAM配置可以轻松解决这种情况。

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

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

从未尝试过将SolrDjango集成在一起,但是可以使用Haystack做到这一点。我在同一页上找到了一些有趣的文章,这是它的github

  • 资源需求-网站将托管在VPS上,因此理想情况下,搜索引擎不需要大量的RAM和CPU

Solr在RAM上繁衍,因此如果RAM高,则不必担心Solr

如果您有数十亿条记录,Solr的 RAM使用率会上升到全索引,您可以聪明地利用Delta导入来解决这种情况。如前所述,Solr 只是近乎实时的解决方案

  • 可扩展性

Solr具有高度可伸缩性。看看SolrCloud。它的一些关键功能。

  • 分片(或分片是在多台计算机之间分配索引的概念,比如说索引是否太大)
  • 负载平衡(如果Solrj与Solr云一起使用,它会使用其Round-Robin机制自动处理负载平衡)
  • 分布式搜索
  • 高可用性
  • 其他功能,例如“您的意思是?”,相关搜索等

对于上述情况,你可以使用SpellCheckComponent是挤满了Solr的。还有很多其他功能,SnowballPorterFilterFactory有助于检索记录,例如,如果您键入的是书籍而不是book,那么将显示与book相关的结果。


这个答案主要集中在Apache SolrMySQL上。Django超出范围。

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

详细安装

入门

此处下载Apache Solr。那将是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应用服务器

Jetty位于solr-4.8.1目录的examples文件夹中,因此请在其中导航并启动Jetty Application Server。

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

现在,不要关闭端子,将其最小化并放在一边。

(提示:在start.jar之后使用&来使Jetty Server在后台运行)

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

在自定义端口上运行码头

默认情况下,它在端口8983上运行。您可以在此处或直接在jetty.xml文件内部更改端口。

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

下载JConnector

此JAR文件充当MySQL和JDBC 之间的桥梁,请在此处下载独立于平台的版本

下载后,解压缩该文件夹并将其复制mysql-connector-java-5.1.31-bin.jar并粘贴到lib目录中。

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字段,如果它们相同,则将跳过索引。)

4,修改schema.xml文件

如图所示,将其添加到您的schema.xml中。

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

实作

索引编制

这才是真正的交易。您需要对从MySQLSolr的数据进行索引,以利用Solr查询。

第1步:转到Solr管理面板

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

这是主要的Apache Solr管理面板

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

第2步:检查您的日志

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

这是Apache Solr引擎的日志记录部分

很好,没有错误。我们很好。让我们从如图所示的列表中选择collection1,然后选择Dataimport

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

使用DIH,你将连接到MySQL的Solr的通过配置文件DB数据-config.xml中Solr的接口和检索其编入索引到数据库中的10条记录Solr的

为此,选择“ 完全导入”,然后选中“ 清除提交 ”选项。现在,如图所示,单击执行

另外,您也可以像这样直接使用完全导入查询。

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

数据导入处理程序

单击Execute之后Solr开始对记录进行索引,如果有任何错误,它将显示Indexing Failed,并且您必须返回到Logging部分以查看出了什么问题。

假设此配置没有错误,并且索引成功完成,您将收到此通知。

索引成功

步骤4:运行Solr查询

似乎一切顺利,现在您可以使用Solr查询来查询已索引的数据。单击左侧的查询,然后按底部的执行按钮。

您将看到所示的索引记录。

用于列出所有记录的相应Solr查询为

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

索引数据

好吧,这里有所有10个索引记录。说,我们只需要以Ja开头的名称,在这种情况下,您需要定位列名solr_name,因此查询如下。

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

以Ja *开头的JSON数据

这就是您编写Solr查询的方式。要了解更多信息,请查看这篇精美的文章


3
@Downvoter,请随时评论或编辑此答案,并且对downvote进行推理也将对其他人有所帮助。
Shankar Damodaran

4
这是我在SO上看到的最全面,组织最严谨的帖子之一。极好的工作。
退化

28

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

但是它没有像+或AND这样的用户友好搜索运算符(使用&|!),并且我对它在其文档站点上的工作方式并不感到兴奋。尽管结果片段中的匹配项用粗体显示,但匹配项的默认算法并不理想。另外,如果要为rtf,PDF,MS Office编制索引,则必须查找并集成文件格式转换器。

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

在所有情况下,Lucene / Solr和Sphinx都很棒。它们是可靠的代码,并且在可用性方面有了很大的改进,因此这些工具无所不在,可以使几乎每个人都满意的搜索。

对于SHAILI-SOLR包括Lucene搜索代码库,并且具有成为一个不错的独立搜索引擎的组件。


1
我相信PostgreSQL全文搜索是指Tsearch。但是Tsearch 支持短语搜索。它仍然在他们的TODO列表sai.msu.su/~megera/wiki/FTS_Todo上
迦南姆2010年

1
刚刚对Postgres 9.0全文搜索进行了一系列测试;如果用户忘记正确使用所有重音,发现法语文本不匹配,我们感到非常失望。单词形式的匹配是不完整的-例如,在英语中,“ say”与包含“ said”的文本不匹配。尽管在所有测试语言(en,fr,ru)中具有集成功能,但总体而言还是相当不错的。
罗曼·斯塔科夫

9
@romkyns:您需要安装一个不重音字典以将其删除。
Denis de Bernardy 2011年

2
“ OTOH,它比MySQL文本搜索更好,后者甚至不索引三个字母或更少的单词。” 这不是MySQL的内置限制,而是您在配置文件中设置的任何内容。如果要索引一个字母的单词,只需在配置中更改一个值。
Canuck

1
令人担忧的是,人们正在对尚未充分探索的数据库进行比较。MySQL CAN可以将三个或三个以下字符的单词编入索引-您只需对其进行正确配置。
TheCarver

22

我只花了两分钱就解决了这个老问题。我强烈建议您看一下ElasticSearch

Elasticsearch是基于Lucene的搜索服务器。它提供了具有RESTful Web界面和无模式JSON文档的分布式,多租户的全文本搜索引擎。Elasticsearch是用Java开发的,并根据Apache许可的条款作为开源发布。

与其他FTS(全文搜索)引擎相比,其优势在于:

  • RESTful接口
  • 更好的可扩展性
  • 大型社区
  • 由Lucene开发人员构建
  • 广泛的文档
  • 有许多可用的开源库(包括Django)

我们在项目中使用了该搜索引擎,对此感到非常满意。


10

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

仅供参考,至少从 MySQL 5.0 起 MySQL全文的最小字长是可调的。谷歌“ mysql全文最小长度”的简单说明。

就是说,MySQL全文有局限性:一方面,一旦达到一百万条左右的记录,更新速度就会变慢,...


2

我将mnoGoSearch添加到列表中。极为高效且灵活的解决方案,可像Google一样工作:索引器可从多个站点获取数据,您可以使用基本条件,也可以发明自己的挂钩来获得最佳搜索质量。它还可以直接从数据库中获取数据。

该解决方案目前尚不为人所知,但可以满足最大需求。您可以编译并安装它,也可以在独立服务器上,甚至在您的主体服务器上,它都不需要Solr这样的资源,因为它是用C编写的,甚至可以在小型服务器上完美运行。

首先,您需要自己编译,因此需要一些知识。我为Debian 写了一个小脚本,可以帮上忙。欢迎任何调整。

当您使用Django框架时,您可以在中间使用或PHP客户端,或者在Python中找到解决方案,我看到了一些 文章

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.