ChatGPT解决这个技术问题 Extra ChatGPT

全文搜索引擎对比——Lucene、Sphinx、Postgresql、MySQL? [关闭]

关闭。此问题不符合 Stack Overflow 准则。它目前不接受答案。我们不允许提出有关书籍、工具、软件库等建议的问题。您可以编辑问题,以便可以用事实和引用来回答它。 5个月前关闭。社区在 5 个月前审查了是否重新打开此问题并将其关闭:原始关闭原因未解决 改进此问题

我正在构建一个 Django 站点,并且正在寻找一个搜索引擎。

几个候选人:

Lucene/Lucene 与 Compass/Solr

狮身人面像

Postgresql 内置全文搜索

MySQl 内置全文搜索

选择标准:

结果相关性和排名

搜索和索引速度

易于使用且易于与 Django 集成

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

可扩展性

额外的功能,例如“你的意思是?”、相关搜索等

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

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

2¢:MySQL 全文搜索和事务(目前)是互斥的。 MySQL 全文索引需要不支持事务的 MyISAM 表类型。 (与支持事务但不支持全文索引的 InnoDB 表类型相反。)
PostgreSQL 全文搜索,Tsearch支持短语搜索。但是,它在 TODO 列表 sai.msu.su/~megera/wiki/FTS_Todo 上。
任何查看 Django 的人都应该查看 haystack 应用程序。 haystacksearch.org
@CarlG,仅供大家参考。 MySQL 5.6+ 具有 innodb 引擎的全文搜索支持

p
pat

很高兴看到有人对 Lucene 发表意见——因为我对此一无所知。

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

结果相关性排名是默认值。您可以根据需要设置自己的排序,并为特定字段赋予更高的权重。

索引速度非常快,因为它直接与数据库对话。任何缓慢都来自复杂的 SQL 查询和未索引的外键以及其他此类问题。我也从未注意到搜索有任何缓慢。

我是 Rails 人,所以我不知道用 Django 实现它有多容易。不过,Sphinx 源代码附带了一个 Python API。

搜索服务守护程序 (searchd) 的内存使用量非常低 - 您也可以设置索引器进程使用多少内存的限制。

可扩展性是我的知识比较粗略的地方 - 但是将索引文件复制到多台机器并运行多个 searchd 守护程序很容易。不过,我从其他人那里得到的总体印象是,它在高负载下非常好,因此在多台机器上扩展它并不是需要处理的事情。

不支持'did-you-mean'等-尽管这些可以使用其他工具轻松完成。 Sphinx 虽然使用字典来做词干,所以“驾驶”和“驾驶”(例如)在搜索中会被认为是相同的。

Sphinx 不允许字段数据的部分索引更新。常见的方法是维护一个包含所有最近更改的增量索引,并在每次更改后重新索引(这些新结果会在一两秒内出现)。由于数据量很小,这可能需要几秒钟的时间。不过,您仍然需要定期重新索引主数据集(尽管多久定期取决于数据的波动性 - 每天?每小时?)。不过,快速的索引速度让这一切都变得非常轻松。

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

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


Sphinx 确实允许您更新当前索引中项目的单个属性,但不能删除/更新完整记录。
sphinx RT 允许您进行部分更新/删除。它处于早期阶段,但已经 [几乎] 有效。 sphinxsearch.com/wiki/doku.php?id=rt_tutorial
Here is an answer on Solr 这是 Sphinx 上这个答案的好搭档
没有什么能比得上 Sphinx 的速度,所以如果速度是您的首要关注点,那么 Sphinx 就是您的选择。好贴
Sphinx 2.3.2 Beta 现在有一个名为“CALL SUGGEST”的功能,可用于实现“您的意思是?” sphinxsearch.com/docs/devel.html#sphinxql-call-suggest
M
Michiel de Mare

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

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

至于 CPU 和 RAM 要求,在 Lucene 中执行搜索不会对您的 CPU 执行过多的任务,尽管索引您的数据是,尽管您不经常这样做(可能一天一次或两次),所以这不是很大的障碍。

它并不能回答你所有的问题,但简而言之,如果你有大量的数据要搜索,并且你想要出色的性能,那么我认为 Lucene 绝对是要走的路。如果您不打算搜索那么多数据,那么您不妨进行数据库全文搜索。在我的书中,设置 MySQL 全文搜索肯定更容易。


与 sphinx 相比,lucence 太慢且太笨重。我在我的项目中都使用过,最后我还是坚持使用 sphinx。 Lucence 在 java 中,它比 Sphinx 需要更多的 CPU 和 RAM。
我不得不在这里不同意。如果你建立了一个正确的索引,Lucene 的速度很快。您基本上可以在几毫秒内对数百万条记录进行高级查询。你只需要知道你在做什么。 Lucene 在 java 中……你的意思是?还有 .NET 端口,Lucene.NET 顺便说一句。
但是您明确表示您不使用狮身人面像,并且 v3sson 两者都使用了。
你怎么能在你说你没有使用 sphinx 的同一句话中说 lucene 的性能是无与伦比的?
有效的问题。我从来没有说过 Lucene 比 Sphinx 快,我提到 Lucene 与数据库全文搜索是无与伦比的。它是。对此毫无疑问。 Lucene 基于倒排索引。现在我不知道 Sphinx,如前所述,但如果它也使用倒排索引或类似的索引方法,那么它们的性能可能相同。说 Lucene 与 Sphinx 相比“太慢太笨重”并不是基于事实。尤其是当只说 Lucene 在“Java”中时,这在性能方面只是一个荒谬的非问题。
S
Shankar Narayana Damodaran

阿帕奇索尔

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

简单介绍

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

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

Solr 在高流量 Web 应用程序上运行良好(我在某处读到它不适合此,但我支持该声明)。它使用 RAM,而不是 CPU。

结果相关性和排名

提升可帮助您将结果排在首位。假设您尝试在 firstname 和 lastname 字段中搜索名称 john,并且您希望与 firstname 字段相关,那么您需要提升 firstname 字段,如图所示。

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

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

更多关于SolrRelevancy

搜索和索引速度

速度快得令人难以置信,而且毫不妥协。我搬到 Solr 的原因。

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

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

易于使用且易于与 Django 集成

从未尝试过集成 SolrDjango,但是您可以使用 Haystack 来实现。我发现了一些有趣的 article,这里是它的 github

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

Solr 在 RAM 上繁殖,因此如果 RAM 很高,您不必担心 Solr。

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

可扩展性

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

分片(或分片是在多台机器之间分配索引的概念,比如如果您的索引变得太大)

负载平衡(如果 Solrj 与 Solr 云一起使用,它会使用它的循环机制自动处理负载平衡)

分布式搜索

高可用性

额外的功能,例如“你的意思是?”、相关搜索等

对于上述场景,您可以使用与 Solr 一起打包的 SpellCheckComponent。还有很多其他功能,SnowballPorterFilterFactory 有助于检索记录,如果您键入 books 而不是 book,您将看到与 相关的结果书

这个答案广泛关注 Apache Solr 和 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 应用服务器

Jettysolr-4.8.1 目录的示例文件夹中可用,因此请在其中导航并启动 Jetty 应用程序服务器。

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

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

(提示:在 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.表结构

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

执行

索引

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

第 1 步:转到 Solr 管理面板

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

https://i.stack.imgur.com/8grrc.png

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

第 2 步:检查您的日志

好的,现在你在这里,你可以有很多黄色消息(警告)。确保您没有将错误消息标记为红色。早些时候,在我们的配置中,我们在 db-data-config.xml 中添加了一个选择查询,假设该查询有任何错误,它会显示在这里。

https://i.stack.imgur.com/8l6n5.png

很好,没有错误。我们可以走了。如图所示,让我们从列表中选择 collection1 并选择 Dataimport

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

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

为此,请选择 full-import ,然后选中 Clean 和 Commit 选项。现在单击执行,如图所示。

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

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

https://i.stack.imgur.com/sHvSO.png

单击 Execute 后,Solr 开始索引记录,如果有任何错误,它会显示 Indexing Failed,您必须返回 Logging 部分查看出现了什么问题。

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

https://i.stack.imgur.com/WlD07.png

第 4 步:运行 Solr 查询

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

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

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

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

https://i.stack.imgur.com/aZP9W.png

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

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

https://i.stack.imgur.com/qeArE.png

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


@Downvoter,请随时评论或编辑此答案,并且反对投票的推理也将对其他人有所帮助。
这是我在 SO 上看到的最全面和组织良好的帖子之一。好工作。
C
Community

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

以下链接中的答案详细介绍了有关 Sphinx 的一些内容,这些内容也适用于 Solr。 Comparison of full text search engine - Lucene, Sphinx, Postgresql, MySQL?

Solr 还提供以下附加功能:

支持复制 多核(将这些视为具有自己的配置和索引的独立数据库) 布尔搜索 突出显示关键字(如果您有 regex-fu,在应用程序代码中很容易做到;但是,为什么不让专门的工具做得更好为您工作)通过 XML 或分隔文件更新索引 通过 HTTP 与搜索服务器通信(它甚至可以返回 Json、原生 PHP/Ruby/Python) PDF、Word 文档索引 动态字段 Facets 聚合字段 停用词、同义词等 更多像这样... 使用自定义查询直接从数据库中索引 自动建议缓存自动预热 快速索引(与 MySQL 全文搜索索引时间相比)——Lucene 使用二进制倒排索引格式。提升(用于增加特定关键字或短语等相关性的自定义规则)该字段被搜索而不是所有内容 - 更好的用户体验)

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

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


Sphinx 也支持复制 多核布尔搜索 突出显示关键字 通过 XML 更新索引 - 或分隔文件 - PDF、Word 文档索引(通过 xml) Facets 停用词、同义词等 使用自定义查询直接从数据库中索引 自动建议快速indexing Boosting Fielded search 关于动态字段 聚合字段 缓存自动升温 我只是不知道
S
SearchTools-Avi

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

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

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

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

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


我相信通过 PostgreSQL 全文搜索,您指的是 Tsearch。但是Tsearch支持词组搜索。它仍在他们的 TODO 列表 sai.msu.su/~megera/wiki/FTS_Todo 上。
刚刚在 Postgres 9.0 全文搜索上做了一堆测试;如果用户忘记正确使用所有的口音,就会发现法语文本不匹配,这让我感到很失望。单词形式的匹配是不完整的——例如,英语中的“say”与包含“said”的文本不匹配。总体而言,尽管对于测试的语言(en、fr、ru)的集成功能而言,它还是相当令人印象深刻的。
@romkyns:您需要安装一个非重音字典才能将它们删除。
“OTOH,它比 MySQL 文本搜索要好得多,它甚至不索引三个字母或更少的单词。”这不是 MySQL 的内置限制——它是您在配置文件中设置的任何内容。如果要索引一个字母的单词,只需更改配置中的一个值。
令人担忧的是,人们正在对他们尚未完全探索的数据库进行比较。 MySQL 可以索引三个或更少字符的单词——你只需要正确配置它。
v
vooD

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

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

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

RESTful 接口

更好的可扩展性

大型社区

由 Lucene 开发人员构建

广泛的文档

有许多可用的开源库(包括 Django)

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


B
BJ.

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

仅供参考,MySQL 全文最小字长至少从 MySQL 5.0 开始是可调整的。谷歌'mysql全文最小长度'以获得简单的说明。

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


F
Fedir RYKHTIK

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

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

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

由于您使用的是Django框架,您可以在中间使用PHP客户端,或者在Python中找到解决方案,我看到了some articles

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


t
thmarx

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


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅