447

我目前正在寻找其他搜索方法,而不是使用庞大的 SQL 查询。我最近看到了elasticsearch,并且玩过whoosh(搜索引擎的 Python 实现)。

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

4

9 回答 9

808

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

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

就 Lucene 的可用性而言,早在我创建 Compass 的时候(差不多 6 年了)。它的目的是简化 Lucene 的使用,让日常的 Lucene 变得更简单。我一次又一次遇到的是能够分发 Compass 的要求。我开始在 Compass 内部进行工作,通过与 GigaSpaces、Coherence 和 Terracotta 等数据网格解决方案集成,但这还不够。

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

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

Solr 也是一种通过 HTTP 公开索引/搜索服务器的解决方案,但我认为ElasticSearch提供了一个非常出色的分布式模型和易用性(尽管目前缺乏一些搜索功能,但不会长久,并且在任何在这种情况下,计划是将所有Compass功能都纳入 ElasticSearch)。当然,我是有偏见的,因为我创建了 ElasticSearch,所以你可能需要自己检查。

至于Sphinx,我没用过,所以不能评论。我可以向您推荐的是Sphinx 论坛上的这个帖子,我认为它证明了 ElasticSearch 的优越分布式模型。

当然,ElasticSearch 的功能远不止分布式。它实际上是在考虑云的情况下构建的。您可以查看网站上的功能列表。

于 2010-02-18T11:31:13.760 回答
72

我使用过 Sphinx、Solr 和 Elasticsearch。Solr/Elasticsearch 建立在 Lucene 之上。它添加了许多常用功能:Web 服务器 API、分面、缓存等。

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

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

一些示例用法:

  • 狮身人面像:craigslist.org
  • Solr:Cnet、Netflix、digg.com
  • 弹性搜索:Foursquare、Github
于 2010-02-16T23:11:35.113 回答
67

我们经常使用 Lucene 来索引和搜索数以千万计的文档。搜索足够快,我们使用不需要很长时间的增量更新。我们确实花了一些时间才到这里。Lucene 的优势在于它的可扩展性、广泛的特性和活跃的开发者社区。使用裸 Lucene 需要使用 Java 编程。

如果您重新开始,Lucene 系列中适合您的工具是Solr,它比裸 Lucene 更容易设置,并且几乎具有 Lucene 的所有功能。它可以轻松导入数据库文档。Solr 是用 Java 编写的,因此对 Solr 的任何修改都需要 Java 知识,但是您可以通过调整配置文件来做很多事情。

我还听说过关于 Sphinx 的好消息,尤其是与 MySQL 数据库结合使用时。不过没用过。

IMO,您应该根据以下选择:

  • 所需的功能 - 例如,您需要法语词干分析器吗?Lucene 和 Solr 有一个,我不知道其他的。
  • 精通实现语言 - 如果您不了解 Java,请不要接触 Java Lucene。您可能需要 C++ 来处理 Sphinx。Lucene 也被移植到其他 语言中。如果您想扩展搜索引擎,这一点非常重要。
  • 易于实验——我相信 Solr 在这方面是最好的。
  • 与其他软件的接口——Sphinx 与 MySQL 有很好的接口。Solr 支持 ruby​​、XML 和 JSON 接口作为 RESTful 服务器。Lucene 只允许您通过 Java 进行编程访问。CompassHibernate Search是 Lucene 的包装器,将其集成到更大的框架中。
于 2010-02-16T10:51:22.503 回答
23

我们在具有 10.000.000 + 条 MySql 记录和 10 多个不同数据库的垂直搜索项目中使用 Sphinx。它对 MySQL 有非常出色的支持,在索引方面有很高的性能,研究速度很快但可能比 Lucene 差一点。但是,如果您需要每天快速建立索引并使用 MySQL 数据库,那么它是正确的选择。

于 2010-11-28T01:14:41.013 回答
18

比较 ElasticSearch 和 Solr的实验

于 2011-05-12T15:32:55.690 回答
13

我的 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 ]

狮身人面像查询时间:

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)
于 2012-05-01T03:29:15.853 回答
8

到目前为止,我能找到的唯一 elasticsearch 与 solr 性能比较是:

Solr vs elasticsearch 死斗!

于 2011-04-03T19:20:06.047 回答
7

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

我没有使用过 Sphinx,但我知道人们对其速度和近乎神奇的“易于设置到令人敬畏”的比率发誓。

于 2010-02-18T06:20:20.373 回答
7

尝试索引罐。

作为弹性搜索的例子,它被认为比 lucene/solr 更容易使用。它还包括非常灵活的评分系统,无需重新索引即可进行调整。

于 2011-02-08T15:41:15.707 回答