私は現在、巨大な SQL クエリを使用するのではなく、他の検索方法を検討しています。最近、elasticsearchを見て、 whoosh (検索エンジンの Python 実装) で遊んでみました。
選んだ理由を教えてください。
私は現在、巨大な SQL クエリを使用するのではなく、他の検索方法を検討しています。最近、elasticsearchを見て、 whoosh (検索エンジンの Python 実装) で遊んでみました。
選んだ理由を教えてください。
ElasticSearch の作成者として、なぜ私が最初に ElasticSearch を作成したのかについて説明できるかもしれません :)。
純粋な Lucene を使用するのは困難です。実際にうまく機能させたい場合は、注意が必要なことがたくさんあります。また、ライブラリであるため、分散サポートはなく、維持する必要があるのは組み込みの Java ライブラリにすぎません。
Lucene の使いやすさに関して言えば、私が Compass を作成したのは 6 年ほど前のことです。その目的は、Lucene を使用して単純化し、毎日の Lucene をより単純にすることでした。私が何度も遭遇したのは、Compass を配布できるようにするための要件です。GigaSpaces、Coherence、Terracotta などのデータ グリッド ソリューションと統合することで、Compass 内から作業を開始しましたが、それだけでは十分ではありません。
根本的に、分散 Lucene ソリューションはシャーディングする必要があります。また、ユビキタス API としての HTTP と JSON の進歩により、さまざまな言語のさまざまなシステムを簡単に使用できるソリューションを意味します。
これが、先に進んで ElasticSearch を作成した理由です。非常に高度な分散モデルを持ち、JSON をネイティブに話し、多くの高度な検索機能を公開し、すべてが JSON DSL によってシームレスに表現されます。
Solr は、HTTP 経由でインデックス作成/検索サーバーを公開するためのソリューションでもありますが、ElasticSearchははるかに優れた分散モデルと使いやすさを提供すると主張します (ただし、現在、検索機能の一部が欠けていますが、長くはありません。その場合、Compassのすべての機能を ElasticSearch に組み込む予定です)。もちろん、私は ElasticSearch を作成したので偏見があるので、自分で確認する必要があるかもしれません。
Sphinxについては、使ったことがないのでコメントできません。私が参考にできるのは、Sphinx フォーラムのこのスレッドで、ElasticSearch の優れた分散モデルを証明していると思います。
もちろん、ElasticSearch には分散型以外にも多くの機能があります。実際には、クラウドを念頭に置いて構築されています。サイトで機能一覧を確認できます。
Sphinx、Solr、Elasticsearch を使用しました。Solr/Elasticsearch は Lucene の上に構築されています。Web サーバー API、ファセット、キャッシュなど、多くの一般的な機能が追加されます。
単純な全文検索のセットアップだけが必要な場合は、Sphinx を選択することをお勧めします。
検索をカスタマイズしたい場合は、Elasticsearch と Solr を選択することをお勧めします。これらは非常に拡張性が高く、独自のプラグインを作成して結果のスコアを調整できます。
いくつかの使用例:
私たちは定期的に Lucene を使用して、何千万ものドキュメントのインデックス作成と検索を行っています。検索は十分に高速で、時間がかからない増分更新を使用しています。ここにたどり着くまでに時間がかかりました。Lucene の強みは、そのスケーラビリティ、広範な機能、および開発者の活発なコミュニティです。裸の Lucene を使用するには、Java でプログラミングする必要があります。
新たに始める場合、Lucene ファミリーのツールはSolrです。これは、裸の Lucene よりもセットアップがはるかに簡単で、Lucene のほとんどすべての機能を備えています。データベース文書を簡単にインポートできます。Solr は Java で記述されているため、Solr を変更するには Java の知識が必要ですが、構成ファイルを微調整するだけで多くのことができます。
また、特に MySQL データベースと組み合わせて、Sphinx について良いことも聞いています。ただし、使用していません。
IMO、次に従って選択する必要があります。
10.000.000 以上の MySql レコードと 10 以上の異なるデータベースを持つ垂直検索プロジェクトで Sphinx を使用しています。MySQL のサポートが非常に優れており、インデックス作成のパフォーマンスが高いため、調査は高速ですが、Lucene よりも少し劣る場合があります。ただし、毎日すばやくインデックスを作成する必要があり、MySQL データベースを使用する場合は、これが正しい選択です。
ElasticSearchと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)
これまでに見つけた唯一のelasticsearchとsolrのパフォーマンス比較は次のとおりです。
Lucene は素晴らしいのですが、ストップ ワード セットがひどいです。StopAnalyzer.ENGLISH_STOP_WORDS_SET に大量のストップ ワードを手動で追加して、使用可能な状態に近づける必要がありました。
私は Sphinx を使用したことはありませんが、人々がそのスピードと魔法のような「セットアップのしやすさと素晴らしさ」の比率を自慢していることは知っています。
インデックスタンクを試してください。
弾性検索の場合、lucene/solr よりもはるかに使いやすいと考えられていました。また、再インデックスせずに微調整できる非常に柔軟なスコアリング システムも含まれています。