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

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


当前回答

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

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

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

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

The required functionality - e.g. do you need a French stemmer? Lucene and Solr have one, I do not know about the others. Proficiency in the implementation language - Do not touch Java Lucene if you do not know Java. You may need C++ to do stuff with Sphinx. Lucene has also been ported into other languages. This is mostly important if you want to extend the search engine. Ease of experimentation - I believe Solr is best in this aspect. Interfacing with other software - Sphinx has a good interface with MySQL. Solr supports ruby, XML and JSON interfaces as a RESTful server. Lucene only gives you programmatic access through Java. Compass and Hibernate Search are wrappers of Lucene that integrate it into larger frameworks.

其他回答

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

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

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

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

The required functionality - e.g. do you need a French stemmer? Lucene and Solr have one, I do not know about the others. Proficiency in the implementation language - Do not touch Java Lucene if you do not know Java. You may need C++ to do stuff with Sphinx. Lucene has also been ported into other languages. This is mostly important if you want to extend the search engine. Ease of experimentation - I believe Solr is best in this aspect. Interfacing with other software - Sphinx has a good interface with MySQL. Solr supports ruby, XML and JSON interfaces as a RESTful server. Lucene only gives you programmatic access through Java. Compass and Hibernate Search are wrappers of Lucene that integrate it into larger frameworks.

我用过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提供了一个更优秀的分布式模型和易用性(尽管目前缺少一些搜索功能,但不会持续太久,而且无论如何,计划是将所有Compass功能纳入ElasticSearch)。当然,我有偏见,因为我创建了ElasticSearch,所以你可能需要自己检查。

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

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

我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)