全文search引擎比较 – Lucene,Sphinx,Postgresql,MySQL?

我build立一个Django网站,我正在寻找一个search引擎。

几名候选人:

  • 带有Compass / Solr的Lucene / Lucene

  • 狮身人面像

  • Postgresql内置全文search

  • MySQl内置全文search

select标准:

  • 结果相关性和排名
  • search和索引速度
  • 易用性和易于与Django集成
  • 资源需求 – 站点将被托pipe在VPS上 ,因此理想的search引擎不需要大量的RAM和CPU
  • 可扩展性
  • 额外的function,如“你的意思?”,相关search等

任何人都有上述search引擎的经验,或其他引擎不在列表中 – 我很想听听你的意见。

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

很高兴看到有人对Lucene的声音 – 因为我不知道这一点。

另一方面,狮身人面像,我很清楚,所以让我们看看我能否得到一些帮助。

  • 结果相关性排名是默认值。 您可以根据自己的意愿设置自己的分类,并给予特定的分数更高的权重。
  • 索引速度是超快的,因为它直接与数据库对话。 任何缓慢都将来自复杂的SQL查询和未索引的外键等问题。 我从来没有注意到任何search缓慢。
  • 我是一个Rails的人,所以我不知道用Django实现是多么容易。 尽pipe有狮身人面像来源的Python API。
  • search服务守护进程(searchd)在内存使用上相当低 – 您可以设置索引器进程使用的内存限制。
  • 可伸缩性是我的知识更粗略的地方 – 但是将索引文件复制到多台机器并运行多个searchd守护进程是非常简单的。 我从别人那里得到的一般印象是,在高负载下它是非常好的,所以在多台机器上扩展是不需要处理的。
  • 不支持“你的意思”等,虽然这些可以很容易地用其他工具完成。 狮身人面像虽然使用字典干扰词,所以“驾驶”和“驱动”(例如)将在search中被认为是相同的。
  • 虽然狮身人面像不允许部分索引更新字段数据。 常见的做法是维护一个包含所有最近变化的增量指数,并在每次变化后重新编制索引(新的结果出现在一两秒内)。 由于数据量小,这可能需要几秒钟的时间。 尽pipe如此,您仍需要定期对主要数据集进行重新编制索引(尽pipe每隔一小时每隔一段时间,数据的波动程度如何)。 快速的索引速度让这一切都非常痛苦。

我不知道这是怎么适用于你的情况,但是Evan Weaver比较了几个常见的Railssearch选项 (Sphinx,Ferret(Lucene for Ruby的一个端口)和Solr),运行了一些基准testing。 我想可能是有用的。

我还没有深入探讨MySQL的全文search的深度,但是我知道它不能与Sphinx,Lucene或Solr进行速度和function上的竞争。

我不知道Sphinx,但是至于Lucene vs数据库全文search,我认为Lucene的性能是无与伦比的。 只要你已经正确地设置了你的Lucene索引,你应该能够在不到10毫秒内完成任何search,无论你需要search多less条logging。

尽pipe这是最大的障碍:个人而言,我认为将Lucene集成到您的项目中并不容易 。 当然,设置它并不难,所以你可以做一些基本的search,但是如果你想从中获得最大的性能,那么你肯定需要一本关于Lucene的好书。

至于CPU和RAM的要求,在Lucene中执行search并不会太多地处理你的CPU,虽然索引你的数据是尽pipe你不经常这样做(可能一天一次或两次),所以不是很多障碍。

它并不回答你所有的问题,但总之,如果你有很多数据需要search,而且你需要很好的性能,那么我认为Lucene肯定是一个很好的select。 如果你不会有那么多的数据要search,那么你不妨去数据库全文search。 在我的书中设置MySQL全文search是绝对容易的。

我很惊讶没有更多关于Solr的信息。 Solr与狮身人面像非常相似,但具有更高级的function(AFAIK,因为我没有使用狮身人面像 – 只读了它)。

在下面的链接的答案详细介绍了一些关于狮身人面像也适用于Solr的一些事情。 全文search引擎比较 – Lucene,Sphinx,Postgresql,MySQL?

Solr还提供以下附加function:

  1. 支持复制
  2. 多核心(将它们视为具有自己的configuration和自己的索引的独立数据库)
  3. 布尔search
  4. 突出显示关键字(如果有正则expression式,在应用程序代码中相当容易;但是,为什么不让专门的工具为您做得更好)
  5. 通过XML或分隔文件更新索引
  6. 通过HTTP与search服务器进行通信(甚至可以返回Json,Native PHP / Ruby / Python)
  7. PDF,Word文档索引
  8. dynamic字段
  9. 汇总字段
  10. 阻止单词,同义词等
  11. 更多像这样…
  12. 直接从数据库索引自定义查询
  13. 自动build议
  14. cachingAutowarming
  15. 快速索引(与MySQL全文search索引时间比较) – Lucene使用二进制倒排索引格式。
  16. 提高(自定义规则增加特定关键字或短语的相关性等)
  17. 实际search(如果search用户知道他/她想search的字段,则通过键入字段,然后input值来缩小search范围,并且只search该字段而不是所有内容 – 用户体验好得多)

顺便说一句,还有吨更多的function; 然而,我只列出了我在生产中实际使用的function。 顺便提一下,MySQL支持上面列表中的#1,#3和#11(有限)。 对于您正在查找的function,关系数据库不会削减它。 我会立即消除这些。

此外,另一个好处是,Solr(实际上,Lucene实际上)是一个文档数据库(如NoSQL),所以其他文档数据库的许多好处可以用Solr来实现。 换句话说,你可以使用它不仅仅是search(即性能)。 获得创意:)

Apache Solr


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

简单的介绍


任何人都有上述search引擎的经验,或其他引擎不在列表中 – 我很想听听你的意见。

Solr不应该被用来解决实时问题。 对于search引擎, Solr是相当多的游戏和完美的作品。

Solr在高stream量的Web应用程序上工作得很好( 我在某处读到它不适合这个,但是我正在备份这个声明 )。 它利用RAM,而不是CPU。

  • 结果相关性和排名

提升可以帮助您将结果排在最前面。 比方说,你正试图在名字姓氏的字段中search一个名字john ,并且你想要给名字字段赋予相关性,那么你需要提升 名字字段,如图所示。

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

正如你所看到的, 名字字段提高了2分。

更多关于SolrRelevancy

  • search和索引速度

速度令人难以置信的快速,没有妥协。 我搬到Solr的原因。

关于索引速度, Solr也可以处理数据库表中的JOINS 。 更高和更复杂的JOIN会影响索引速度。 但是,巨大的RAMconfiguration可以轻松解决这种情况。

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

  • 易用性和易于与Django集成

从来没有试图整合SolrDjango ,但是你可以通过Haystack来实现。 我发现了一些有趣的文章 ,在这里是它的github 。

  • 资源需求 – 站点将被托pipe在VPS上,因此理想的search引擎不需要大量的RAM和CPU

Solr品种在RAM上,所以如果RAM高,你不必担心Solr

如果你有几十亿条logging, Solr的内存使用率就会上升到全索引,你可以巧妙地利用Deltaimport来解决这个问题。 如上所述, Solr 只是一个接近实时的解决scheme

  • 可扩展性

Solr具有高度的可扩展性。 看看SolrCloud 。 它的一些关键特点。

  • 碎片(或分片是在多台机器中分配索引的概念,比如说你的索引变得太大了)
  • 负载平衡(如果Solrj与Solr云一起使用,它将使用循环机制自动处理负载平衡)
  • 分布式search
  • 高可用性
  • 额外的function,如“你的意思?”,相关search等

对于上面的场景,您可以使用与Solr打包在一起的SpellCheckComponent 。 还有很多其他function, SnowballPorterFilterFactory有助于检索logging,如果您input的是书籍而不是书籍 ,则会显示与书籍相关的结果。


这个答案大致集中在Apache SolrMySQL上 。 Django超出了范围。

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

详细的安装

入门

从这里下载Apache Solr 。 这将是4.8.1版本。 你可以下载新版本,我发现这稳定。

下载归档文件后,将其解压缩到您select的文件夹中。 说.. 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

现在,不要closuresterminal,尽量减less它,让它保持在一边。

(提示:使用&start.jar之后,使Jetty服务器在后台运行)

要检查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

创build要链接到Apache Solr的MySQL表

要使用Solr ,您需要有一些表和数据来search。 为此,我们将使用MySQL创build一个表并推送一些随机的名字,然后我们可以使用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.创builddb-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" /> 

履行

索引

这是真正的交易。 您需要将数据从MySQL索引到Solr ,以便使用Solr查询。

第1步:转到Solrpipe理面板

在浏览器中inputURL http:// localhost:8983 / solr 。 屏幕像这样打开。

这是主要的Apache Solr管理面板

如标记所示,进入Logging in order检查是否有上述configuration导致错误。

第2步:检查你的日志

好吧,现在你在这里,正如你可以有很多黄色的消息(警告)。 确保您没有标记为红色的错误消息。 早些时候,在我们的configuration中,我们在db-data-config.xml中添加了一个select查询,如果查询中有任何错误,就会显示在这里。

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

好,没有错误。 我们很好去。 我们从列表中selectcollection1 ,然后selectDataimport

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

使用DIH,您将通过Solr界面的configuration文件db-data-config.xmlSolr连接到MySQL ,并从索引到Solr的数据库检索10条logging。

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

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

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

数据导入处理程序

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

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

索引成功

步骤4:运行Solr查询

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

您将看到如图所示的索引logging。

列出所有logging的相应Solr查询是

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

索引的数据

那么,所有10个索引logging。 说,我们只需要以Ja开头的名字,在这种情况下,你需要定位列名solr_name ,因此你的查询就像这样。

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

以Ja *开头的JSON数据

这就是你如何编写Solr查询。 阅读更多关于它,请检查这个美丽的文章 。

我现在正在查看PostgreSQL全文search,它具有现代search引擎的所有function,非常好的扩展特性和多语言支持,与数据库中的文本字段紧密集成。

但它没有用户友好的search运算符,如+或AND(使用&|!),我对它在文档网站上的工作方式并不感到激动。 虽然结果摘录中的匹配项粗体显示,但匹配项的默认algorithm并不好。 另外,如果你想索引rtf,PDF,MS Office,你必须find并整合一个文件格式转换器。

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

在我见过的所有案例中,Lucene / Solr和Sphinx都非常棒 。 它们是可靠的代码,并且随着可用性的显着提高而发展,所以这些工具都可以使search几乎可以满足所有人。

为SHAILI – SOLR包括Lucenesearch代码库,并有组件是一个很好的独立search引擎。

这个老问题就是我的两分钱。 我强烈build议看看ElasticSearch 。

Elasticsearch是一个基于Lucene的search服务器。 它提供了一个分布式,支持多租户的全文search引擎,具有REST风格的Web界面和无模式的JSON文档。 Elasticsearch是用Java开发的,根据Apache许可条款作为开源发布。

与其他FTS(全文search)引擎相比,其优点是:

  • REST风格的界面
  • 更好的可扩展性
  • 大型社区
  • 由Lucene开发人员构build
  • 广泛的文档
  • 有许多开源库(包括Django)

我们正在使用这个search引擎在我们的项目,并非常高兴。

SearchTools-Avi说:“MySQL文本search,甚至没有索引三个字母或更less的单词”。

FYIs,MySQL全文的最小字长是可调的,因为至less MySQL 5.0。 谷歌“全文最小长度”为简单的指示。

也就是说,MySQL的全文有一定的局限性,比如,一旦你达到了一百万条logging,它的更新速度就会变慢,

我会将mnoGoSearch添加到列表中。 性能卓越且灵活的Google解决scheme:索引器从多个站点获取数据,您可以使用基本的标准,或创build自己的钩子来获得最大的search质量。 它也可以直接从数据库中获取数据。

这个解决scheme目前还不是很清楚,但是它需要最大的需求。 您可以编译和安装它,也可以在独立的服务器上,甚至在您的主体服务器上,它不需要像Solr那么多的资源,因为它是用C语言编写的,即使在小型服务器上也能运行。

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

由于您使用的是Django框架,您可以在中间使用PHP客户端,或者在Python中find一个解决scheme,我看到一些 文章 。

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