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

Con*_*ion 308 mysql lucene postgresql full-text-search sphinx

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

一些候选人:

  • Lucene/Lucene与Compass/Solr

  • 狮身人面像

  • Postgresql内置全文搜索

  • MySQl内置全文搜索

选择标准:

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

任何有上述搜索引擎经验的人,或者不在列表中的其他引擎 - 我很想听听你的意见.

编辑:至于索引需求,当用户不断将数据输入网站时,这些数据需要连续编入索引.它不一定是实时的,但理想情况下,新数据会出现在索引中,延迟时间不超过15-30分钟

pat*_*pat 165

很高兴看到有人对Lucene说话 - 因为我对此一无所知.

另一方面,狮身人面像我很清楚,所以让我们看看我是否可以提供一些帮助.

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

我不知道这对你的情况有多适用,但是Evan Weaver比较了一些常见的Rails搜索选项(Sphinx,Ferret(Lucene for Ruby的一个端口)和Solr),运行一些基准测试.我猜可能有用.

我没有探究MySQL全文搜索的深度,但我知道它不会与Sphinx,Lucene或Solr在速度方面或功能方面竞争.

  • [这是Solr的答案](http://stackoverflow.com/questions/1284083/choosing-a-stand-alone-full-text-search-server-sphinx-or-solr)这是一个很好的配对回答斯芬克斯 (4认同)

Raz*_*zie 82

我不知道Sphinx,但至于Lucene对数据库的全文搜索,我认为Lucene的性能是无与伦比的.只要您正确设置了Lucene索引,无论您需要搜索多少条记录,您都应该能够在不到10毫秒的时间内完成任何搜索.

这是最大的障碍:个人而言,我认为将Lucene集成到您的项目中并不容易.当然,设置起来并不难,所以你可以做一些基本的搜索,但是如果你想要最大限度地利用它,并获得最佳性能,那么你肯定需要一本关于Lucene的好书.

至于CPU和RAM的要求,在Lucene中执行搜索并不会给你的CPU带来太多任务,虽然索引你的数据是,虽然你不经常这样做(可能一天一次或两次),所以这不是很大的障碍.

它没有回答你所有的问题,但简而言之,如果你有大量的数据需要搜索,并且你想要很好的表现,那么我认为Lucene绝对是你要走的路.如果您不想搜索那么多数据,那么您也可以选择数据库全文搜索.在我的书中,设置MySQL全文搜索肯定更容易.

  • 我不得不在这里不同意.如果您构建正确的索引,Lucene会快速闪电.您基本上可以在几毫秒内对数百万条记录进行高级查询.你只需要知道你在做什么.Lucene在java中......你的观点是什么?还有.NET端口,Lucene.NET btw. (25认同)
  • 有效问题.我从未说过Lucene比Sphinx更快,我提到Lucene对数据库全文搜索是无与伦比的.它是.毫无疑问.Lucene基于倒排索引.现在我不知道Sphinx,如前所述,但如果它也使用倒排索引或类似的索引方法,那么它们可能同样表现.陈述Lucene与Sphinx相比,"太慢而且笨重"并非基于事实.特别是当只是说Lucene处于'Java'时,这在性能方面只是一个荒谬的非问题. (22认同)
  • 你如何表明lucene的表现在你说你没有使用过狮身人面像的同一句话中是无与伦比的? (19认同)
  • 但你明确表示你不使用sphinx,而v3sson已经使用了两者. (15认同)
  • 与狮身人面像相比,lucence太慢而且笨重.我在我的项目中使用了两者,最后我坚持使用狮身人面像.Lucence在java中,它比Sphinx需要更多的CPU和RAM. (10认同)
  • V3ss0n没有说,在他看来,Lucene很慢,因为它是Java.他说它是Java,它"比Sphinx需要更多的CPU和RAM". (4认同)
  • 假设 Lucene 很慢是因为它在 Java 中是荒谬的。Java 并不慢,热点 vm 是一件艺术品,在大多数情况下,您正确编写的应用程序将比 ac 应用程序运行得更快。我的经验是 Lucene 重量轻,速度快,但有点繁琐。 (2认同)

Wil*_*III 60

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

以下链接的答案详细介绍了Sphinx的一些内容,它也适用于Solr. 全文搜索引擎的比较 - Lucene,Sphinx,Postgresql,MySQL?

Solr还提供以下附加功能:

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

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

此外,另一个好处是Solr(实际上是Lucene)是一个文档数据库(例如NoSQL),因此Solr可以实现任何其他文档数据库的许多好处.换句话说,您不仅可以将其用于搜索(即性能).发挥创意:)


Sha*_*ran 57

Apache Solr


除了回答OP的查询之外,让我从简单的介绍详细的安装实现,Apache Solr提出一些见解.

简单介绍


任何有上述搜索引擎经验的人,或者不在列表中的其他引擎 - 我很想听听你的意见.

Solr不应该用于解决实时问题.对于搜索引擎来说,Solr几乎是游戏并且完美无缺.

Solr在高流量Web应用程序上工作正常(我在某处读到它不适合这个,但我正在备份该声明).它利用RAM,而不是CPU.

  • 结果相关性和排名

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

http://localhost:8983/solr/collection1/select?q=firstname:john^2&lastname:john
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,名字字段提升了2分.

有关SolrRelevancy的更多信息

  • 搜索和索引速度

速度快得令人难以置信,并没有妥协.我搬到索尔的原因.

关于索引速度,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有助于检索记录,如果您键入,书籍而不是书籍,您将看到与书籍相关的结果.


这个答案主要关注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应用程序服务器

Jettysolr-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://本地主机:8983/Solr的

在自定义端口上运行Jetty

默认情况下,它在端口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)
 );
Run Code Online (Sandbox Code Playgroud)

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');
Run Code Online (Sandbox Code Playgroud)

进入核心并添加lib指令

1.导航到

shankar@shankar-lenovo: ~/Downloads/solr-4.8.1/example/solr/collection1/conf
Run Code Online (Sandbox Code Playgroud)

2.修改solrconfig.xml

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

  <lib dir="../../../contrib/dataimporthandler/lib/" regex=".*\.jar" />
  <lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" />
Run Code Online (Sandbox Code Playgroud)

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

<requestHandler name="/dataimport" 
  class="org.apache.solr.handler.dataimport.DataImportHandler" >
    <lst name="defaults">
      <str name="config">db-data-config.xml</str>
    </lst>
</requestHandler>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

(提示:您可以拥有任意数量的实体,但要注意id字段,如果它们相同,则会跳过索引.)

4.修改schema.xml文件

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

<uniqueKey>id</uniqueKey>
<field name="solr_name" type="string" indexed="true" stored="true" />
Run Code Online (Sandbox Code Playgroud)

履行

索引

这是真正的交易.您需要将数据从MySQL索引到Solr才能使用Solr Queries.

第1步:转到Solr管理面板

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

这是主要的Apache Solr管理面板

如标记所示,请转到Logging inorder以检查上述任何配置是否导致错误.

第2步:检查您的日志

好的,现在你在这里,因为你可以有很多黄色信息(警告).确保没有标记为红色的错误消息.之前,在我们的配置中,我们在db-data-config.xml上添加了一个select查询,比如该查询是否有任何错误,它会显示在这里.

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

很好,没有错误.我们很高兴.让我们从列表中选择collection1,然后选择Dataimport

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

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

为此,请选择完全导入,然后选中" 清除提交 "选项.现在单击Execute,如图所示.

或者,您也可以使用这样的直接完全导入查询.

http://localhost:8983/solr/collection1/dataimport?command=full-import&commit=true
Run Code Online (Sandbox Code Playgroud)

数据导入处理程序

单击执行后,Solr开始索引记录,如果有任何错误,它会说索引失败,你必须返回记录部分看看出了什么问题.

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

索引成功

第4步:运行Solr查询

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

您将看到如下所示的索引记录.

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

http://localhost:8983/solr/collection1/select?q=*:*&wt=json&indent=true
Run Code Online (Sandbox Code Playgroud)

索引数据

那么,有10个索引记录.比如,我们只需要以Ja开头的名称,在这种情况下,您需要定位列名称solr_name,因此您的查询就像这样.

http://localhost:8983/solr/collection1/select?q=solr_name:Ja*&wt=json&indent=true
Run Code Online (Sandbox Code Playgroud)

以Ja*开头的JSON数据

这就是你编写Solr Queries的方法.要了解更多信息,请查看这篇精美的文章.

  • 这是我在SO上看到的最全面,组织最好的帖子之一.好工作. (4认同)
  • @Downvoter,随时评论或编辑这个答案,并推理downvote也会帮助其他人. (3认同)

Sea*_*Avi 28

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

但它没有用户友好的搜索运算符,如+或AND(使用&|!),我对它在文档站点上的工作原理并不感到兴奋.虽然在结果片段中有匹配术语的粗体,但匹配术语的默认算法并不是很好.此外,如果要索引rtf,PDF,MS Office,则必须查找并集成文件格式转换器.

OTOH,它比MySQL文本搜索更好,它甚至不会索引三个字母或更少的字母.这是MediaWiki搜索的默认设置,我认为这对最终用户没有好处:http://www.searchtools.com/analysis/mediawiki-search/

在我见过的所有情况下,Lucene/Solr和Sphinx真的很棒.它们是可靠的代码,并且随着可用性的显着改进而发展,因此所有工具都可以使搜索满足几乎每个人.

对于SHAILI - SOLR包含Lucene搜索代码库,其组件是一个不错的独立搜索引擎.

  • @romkyns:你需要安装一个unaccent字典来剥离它们. (9认同)
  • "OTOH,它比MySQL文本搜索更好,它甚至不会索引三个字母或更少的字母." 这不是MySQL的内置限制 - 它是您在配置文件中设置的任何内容.如果要索引单字母单词,只需更改配置中的一个值即可. (2认同)

voo*_*ooD 22

对于这个非常古老的问题,我只差两分钱.我强烈建议你看一下ElasticSearch.

Elasticsearch是一个基于Lucene的搜索服务器.它提供了一个分布式,多租户能力的全文搜索引擎,具有RESTful Web界面和无架构JSON文档.Elasticsearch是用Java开发的,并根据Apache License的条款作为开源发布.

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

  • RESTful界面
  • 更好的可扩展性
  • 大社区
  • 由Lucene开发人员构建
  • 丰富的文档
  • 有许多开源库可用(包括Django)

我们在我们的项目中使用此搜索引擎,并对此非常满意.


小智 10

SearchTools-Avi说"MySQL文本搜索,它甚至不会将三个字母或更少的字母索引."

仅供参考,MySQL全文最小字长可调,因为至少 MySQL 5.0.谷歌'mysql全文最小长度'用于简单说明.

也就是说,MySQL全文有限制:首先,一旦达到一百万条记录,它就会变得很慢,......