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

时间:2009-04-10 10:38:14

标签: mysql postgresql full-text-search lucene sphinx

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

一些候选人:

  • Lucene / Lucene与Compass / Solr

  • 斯芬克斯

  • Postgresql内置全文搜索

  • MySQl内置全文搜索

选择标准:

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

任何有过上述搜索引擎经验的人,或者不在列表中的其他引擎 - 我很乐意听取您的意见。

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

10 个答案:

答案 0 :(得分:162)

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

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

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

我不知道这对你的情况有多适用,但Evan Weaver compared a few of the common Rails search options(Sphinx,Ferret(Lucene for Ruby的一个端口)和Solr)运行一些基准测试。可能有用,我想。

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

答案 1 :(得分:82)

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

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

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

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

答案 2 :(得分:60)

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

以下链接的答案详细介绍了Sphinx的一些内容,它也适用于Solr。 Comparison of full text search engine - 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. Fielding搜索(如果搜索用户知道他/她想要搜索的字段,他们通过键入字段缩小搜索范围,然后输入值,只搜索该字段而不是搜索所有内容 - 更好的用户体验)
  19. 顺便说一句,还有更多功能;但是,我列出了我在制作中实际使用的功能。 BTW,开箱即用,MySQL支持上面列表中的#1,#3和#11(有限)。对于您正在寻找的功能,关系数据库不会削减它。我马上把它们消灭了。

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

答案 3 :(得分:57)

Apache Solr


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

  

简单介绍


  

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

Solr 不应该用于解决实时问题。对于搜索引擎, Solr 非常适合游戏并且完美无缺

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

  
      
  • 结果相关性和排名
  •   

提升可帮助您对结果进行排名。说,您正在尝试在 firstname lastname 字段中搜索名称​​ john ,并且您想要提供相关性 firstname 字段,然后您需要提升向上 firstname 字段,如图所示。

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

如您所见, firstname 字段提升,得分为2。

更多关于SolrRelevancy

  
      
  • 搜索和索引速度
  •   

速度快得令人难以置信,并且没有妥协。我之所以选择 Solr

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

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

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

从未尝试集成 Solr Django ,但您可以通过Haystack实现这一目标。我发现了一些有趣的article,而github就是{。}}。

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

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

Solr的如果您拥有数十亿条记录,则RAM使用量会在全部索引上出现,您可以巧妙地利用Delta导入来解决这种情况。如上所述, Solr 只是一种近乎实时的解决方案

  
      
  • 可扩展性
  •   

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

  • 碎片(或分片是在多台机器之间分配索引的概念,比如你的索引是否变得太大了)
  • 负载平衡(如果Solrj与Solr云一起使用,它会自动负责使用它进行负载均衡的循环机制)
  • Distributed Search
  • 高可用性
  
      
  • 诸如"等额外功能,您的意思是?",相关搜索等
  •   

对于上述情况,您可以使用 Solr 打包的SpellCheckComponent。还有很多其他功能,SnowballPorterFilterFactory有助于检索记录,如果您输入了图书而不是图书,您将看到与< EM>书


这个答案主要关注 Apache Solr &amp;的 MySQL的即可。 Django超出了范围。

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

  

详细安装

入门

here下载 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

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

  

(提示:使用&amp; start.jar后,让Jetty Server在运行中运行   背景)

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

在自定义端口

上运行Jetty

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

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

下载JConnector

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

下载后,解压缩文件夹并复制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.Table Structure

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.Navigate to

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" />
  

实施

索引

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

第1步:转到Solr管理面板

点击浏览器上的网址http://localhost:8983/solr。屏幕打开就像这样。

This is the main Apache Solr Administration Panel

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

第2步:检查您的日志

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

This is the logging section of your Apache Solr engine

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

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

使用DIH,您将通过配置文件 db-data-config.xml Solr 连接到 MySQL < strong> Solr 接口并从数据库中检索10条记录,这些记录被索引到 Solr

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

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

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

The Data Import Handler

点击执行后, Solr 开始为记录编制索引,如果有任何错误,则会说索引失败并且您有返回登录部分,查看出现了什么问题。

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

Indexing Success

第4步:运行Solr查询

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

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

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

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

The indexed data

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

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

The JSON data starting with Ja*

您编写 Solr 查询的方式。要了解有关它的更多信息,请查看这个漂亮的article

答案 4 :(得分:27)

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

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

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

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

SHAILI的

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

答案 5 :(得分:22)

这个非常古老的问题只是我的两分钱。我强烈建议您查看ElasticSearch

  

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

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

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

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

答案 6 :(得分:10)

SearchTools-Avi说“MySQL文本搜索,甚至没有索引三个字母或更少的字母。”

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

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

答案 7 :(得分:2)

我会将mnoGoSearch添加到列表中。极其高效且灵活的解决方案,适用于Google:indexer从多个站点获取数据,您可以使用基本标准,或发明您自己的钩子以获得最高的搜索质量。它也可以直接从数据库中获取数据。

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

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

当你使用Django框架时,你可以在中间使用或者使用PHP客户端,或者在Python中找到解决方案,我看到some articles

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

答案 8 :(得分:0)

我在project中使用过Solr,这是迄今为止最好的。

答案 9 :(得分:0)

我们刚刚从 Elasticsearch 切换到 Postgres Full Text。由于我们已经使用了 Postgres,我们现在省去了保持索引最新的麻烦。 但这只会影响全文搜索。但是,在某些用例中,Elasicsearch 明显更好。也许是方面或类似的东西。