ElasticSearch, Sphinx, Lucene, Solr, Xapian。哪种适合哪种用途?

我目前正在寻找其他搜索方法,而不是有一个巨大的SQL查询。 我最近看到了elasticsearch,并且玩了发出嘶嘶声(一个搜索引擎的Python实现)

你能给出你的选择的理由吗?

171980 次浏览
我们经常使用Lucene来索引和 搜索数千万份文件。 搜索足够快,而且我们用 不执行的增量更新 很长一段时间。我们确实花了一些时间 来这里。的优点 Lucene是它的可扩展性,很大 功能范围和活动范围 开发者社区。使用裸

. Lucene需要Java编程

如果你要重新开始,你在Lucene家族中的工具是Solr,它比裸Lucene更容易设置,并且几乎拥有Lucene的所有功能。它可以很容易地导入数据库文档。Solr是用Java编写的,因此对Solr的任何修改都需要Java知识,但是仅通过调整配置文件就可以完成很多工作。

我也听说过Sphinx的优点,特别是与MySQL数据库的结合。不过还没有用过。

在我看来,你应该根据以下几点来选择:

  • 所需的功能-例如,你需要一个法语词干?Lucene和Solr有一个,其他人我不知道。
  • 熟练使用实现语言——如果你不懂Java,请不要接触Java Lucene。你可能需要用c++来处理Sphinx。Lucene也被移植到了其他 语言中。如果你想扩展搜索引擎,这是非常重要的。
  • 易于实验——我相信Solr在这方面是最好的。
  • 与其他软件的接口——Sphinx与MySQL有一个很好的接口。Solr作为RESTful服务器支持ruby、XML和JSON接口。Lucene只提供通过Java的编程访问。指南针Hibernate搜索是Lucene的包装器,它们将Lucene集成到更大的框架中。

我用过Sphinx、Solr和Elasticsearch。Solr/Elasticsearch是建立在Lucene之上的。它增加了许多常见的功能:web服务器api, faceting,缓存等。

如果您只想要一个简单的全文搜索设置,Sphinx是一个更好的选择。

如果你想定制你的搜索,Elasticsearch和Solr是更好的选择。它们是非常可扩展的:您可以编写自己的插件来调整结果评分。

一些用法示例:

  • 斯芬克斯:craigslist.org
  • 索尔:Cnet, Netflix, digg.com
  • Elasticsearch: Foursquare, Github

Lucene很好,但是他们的停止词集很糟糕。我不得不手动向StopAnalyzer添加大量的停止词。ENGLISH_STOP_WORDS_SET使它接近可用。

我没有使用过Sphinx,但我知道人们对它的速度和近乎神奇的“易于设置与令人惊叹”的比率深信不疑。

作为ElasticSearch的创建者,也许我可以给你一些理由,为什么我首先要创建它:)。

使用纯Lucene具有挑战性。如果你想让它真正表现良好,你需要注意很多事情,而且,它是一个库,所以没有分布式支持,它只是一个你需要维护的嵌入式Java库。

说到Lucene的可用性,早在6年前,我创建了Compass。它的目标是简化Lucene的使用,使Lucene的日常生活更简单。我一次又一次遇到的是能够分发Compass的需求。我从Compass内部开始着手,通过集成GigaSpaces、Coherence和Terracotta等数据网格解决方案,但这还不够。

在其核心,分布式Lucene解决方案需要被分片。此外,随着HTTP和JSON作为无处不在的api的发展,这意味着可以轻松地使用具有不同语言的许多不同系统的解决方案。

这就是我创建ElasticSearch的原因。它有一个非常先进的分布式模型,使用原生JSON,并公开了许多高级搜索功能,所有这些都通过JSON DSL无缝表达。

Solr也是一个通过HTTP公开索引/搜索服务器的解决方案,但我认为ElasticSearch提供了一个更优秀的分布式模型和易用性(尽管目前缺少一些搜索功能,但不会太久,而且无论如何,计划是将所有指南针功能纳入ElasticSearch)。当然,我有偏见,因为我创建了ElasticSearch,所以你可能需要自己检查。

至于Sphinx,我没有使用过,所以我不能评论。我可以参考的是这个帖子在Sphinx论坛,我认为它证明了ElasticSearch优越的分布式模型。

当然,ElasticSearch不仅仅是分布式的,它还有更多的特性。它实际上是用云来建造的。您可以在网站上查看功能列表。

我们在垂直搜索项目中使用Sphinx,有10.000.000 +的MySql记录和10+不同的数据库。 它对MySQL有非常出色的支持,索引性能高,研究速度快,但可能不如Lucene。 但是,如果你每天都需要快速建立索引并使用MySQL数据库,这是正确的选择

indextank试试。

在弹性搜索的情况下,它被认为比lucene/solr更容易使用。它还包括非常灵活的评分系统,可以在没有评分的情况下调整。

我sphinx.conf

source post_source
{
type = mysql


sql_host = localhost
sql_user = ***
sql_pass = ***
sql_db =   ***
sql_port = 3306


sql_query_pre = SET NAMES utf8
# query before fetching rows to index


sql_query = SELECT *, id AS pid, CRC32(safetag) as safetag_crc32 FROM hb_posts




sql_attr_uint = pid
# pid (as 'sql_attr_uint') is necessary for sphinx
# this field must be unique


# that is why I like sphinx
# you can store custom string fields into indexes (memory) as well
sql_field_string = title
sql_field_string = slug
sql_field_string = content
sql_field_string = tags


sql_attr_uint = category
# integer fields must be defined as sql_attr_uint


sql_attr_timestamp = date
# timestamp fields must be defined as sql_attr_timestamp


sql_query_info_pre = SET NAMES utf8
# if you need unicode support for sql_field_string, you need to patch the source
# this param. is not supported natively


sql_query_info = SELECT * FROM my_posts WHERE id = $id
}


index posts
{
source = post_source
# source above


path = /var/data/posts
# index location


charset_type = utf-8
}

测试脚本:

<?php


require "sphinxapi.php";


$safetag = $_GET["my_post_slug"];
//  $safetag = preg_replace("/[^a-z0-9\-_]/i", "", $safetag);


$conf = getMyConf();


$cl = New SphinxClient();


$cl->SetServer($conf["server"], $conf["port"]);
$cl->SetConnectTimeout($conf["timeout"]);
$cl->setMaxQueryTime($conf["max"]);


# set search params
$cl->SetMatchMode(SPH_MATCH_FULLSCAN);
$cl->SetArrayResult(TRUE);


$cl->setLimits(0, 1, 1);
# looking for the post (not searching a keyword)


$cl->SetFilter("safetag_crc32", array(crc32($safetag)));


# fetch results
$post = $cl->Query(null, "post_1");


echo "<pre>";
var_dump($post);
echo "</pre>";
exit("done");
?>

结果:样本

[array] =>
"id" => 123,
"title" => "My post title.",
"content" => "My <p>post</p> content.",
...
[ and other fields ]

Sphinx查询时间:

0.001 sec.

Sphinx查询时间(并发1k):

=> 0.346 sec. (average)
=> 0.340 sec. (average of last 10 query)

MySQL查询时间:

"SELECT * FROM hb_posts WHERE id = 123;"
=> 0.001 sec.

MySQL查询时间(1k并发):

"SELECT * FROM my_posts WHERE id = 123;"
=> 1.612 sec. (average)
=> 1.920 sec. (average of last 10 query)