私は現在、巨大なSQLクエリを持つのではなく、他の検索方法を検討しています。私は最近 elasticsearch を見て、 whoosh (Pythonによる検索エンジンの実装)で遊んだ。
選択の理由を教えてください。
ElasticSearchの作成者として、どうして私が先に行ってそれを最初に作成したのかについての推論をあなたに与えることができます。
純粋なLuceneを使用するのは困難です。本当にうまく機能させたいのであれば、注意が必要なことがたくさんあります。また、そのライブラリーなので、分散サポートはありません。メンテナンスが必要なのは組み込みJavaライブラリーだけです。
Luceneの使いやすさの点では、遡ると(今では6年近く)、Compassを作成しました。その目的は、Luceneを使用して単純化し、日常のLuceneを単純化することでした。私が何度も何度も出くわしたのは、Compassを配布できるようにするための要件です。 GigaSpaces、Coherence、Terracottaなどのデータグリッドソリューションと統合することで、Compass内から作業を始めましたが、それだけでは不十分です。
その核となるのは、分散型Luceneソリューションの分割です。また、ユビキタスAPIとしてのHTTPとJSONの進歩により、さまざまな言語を持つさまざまなシステムを簡単に使用できるようになりました。
これが私が先に行ってElasticSearchを作成した理由です。それは非常に高度な分散モデルを持ち、ネイティブにJSONを話し、そしてすべてJSON DSLを通してシームレスに表現される多くの高度な検索機能を公開します。
SolrはHTTP経由でインデックス作成/検索サーバーを公開するためのソリューションでもありますが、 ElasticSearch ははるかに優れた分散モデルと使いやすさを提供します(ただし現在一部の検索機能には欠けていますが)。長くはありませんが、いずれにせよ、計画はすべてのコンパス機能をElasticSearchに取り込むことです)。 ElasticSearchを作成したので、もちろん、私は偏っています、それであなたはあなた自身をチェックする必要があるかもしれません。
Sphinxに関しては、私はそれを使ったことがないので、コメントすることはできません。私があなたに紹介できるのは Sphinxフォーラムのこのスレッド です。これはElasticSearchの優れた分散モデルを証明していると思います。
もちろん、ElasticSearchには、単に配布されるだけでなく、もっと多くの機能があります。実際にはクラウドを念頭に置いて構築されています。あなたはサイト上の機能リストを確認することができます。
私はSphinx、Solr、Elasticsearchを使用しました。 Solr/ElasticsearchはLuceneの上に構築されています。それは多くの一般的な機能を追加します:ウェブサーバーAPI、ファセット、キャッシュなど。
単純な全文検索の設定をしたいだけなら、Sphinxがより良い選択です。
検索をまったくカスタマイズしたい場合は、ElasticsearchとSolrを選択してください。それらは非常に拡張性があります:あなたはあなた自身の結果をスコアリングを調整するために書くことができます。
いくつかの使用例
私たちは定期的にLuceneを使って数千万の文書の索引付けと検索を行います。検索は十分に速いので、時間がかからない増分更新を使用します。ここに着くまでに少し時間がかかりました。 Luceneの強みは、そのスケーラビリティ、広範囲の機能、および開発者の活発なコミュニティです。裸のLuceneを使用するには、Javaでのプログラミングが必要です。
あなたが新たに始めているならば、Luceneファミリーのあなたのためのツールは Solr で、これは素のLuceneよりセットアップするのがはるかに簡単で、Luceneの力のほとんどすべてを持っています。データベース文書を簡単にインポートできます。 SolrはJavaで書かれているので、Solrを修正するにはJavaの知識が必要ですが、設定ファイルを調整するだけで多くのことができます。
私はSphinxについて、特にMySQLデータベースとの関連で良いことを聞いたことがあります。それを使ったことがない。
IMO、あなたは以下に従って選択するべきです:
私たちは10.000.000以上のMySqlレコードと10以上の異なるデータベースを持つVertical SearchプロジェクトでSphinxを使用します。 MySQLに対する非常に優れたサポートとインデックス作成における高性能を持っています、研究は速いですが、おそらくLuceneより少し少ないです。ただし、毎日すばやくインデックスを作成してMySQL dbを使用する必要がある場合は、これが正しい選択です。
私の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.
スフィンクス問い合わせ時間(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はすてきな人たちですが、彼らが立ち止まったWordセットはひどいものです。私は手動でStopAnalyzer.ENGLISH_STOP_WORDS_SETに大量のストップワードを追加する必要がありました。
私はSphinxを使ったことはありませんが、スピードと魔法に近い「設定のしやすさ」の比で人々が誓うことを私は知っています。
Indextankを試してください。
エラスティックサーチの場合は、lucene/solrよりもずっと使いやすいと考えられていました。また、インデックスを再作成することなく調整できる非常に柔軟な採点システムも含まれています。