나는 현재 거대한 SQL 쿼리를 사용하는 대신 다른 검색 방법을 찾고 있습니다. 최근에 elasticsearch를 보고 whoosh (Python의 검색 엔진 구현)를 사용했습니다.
선택의 이유를 제시 할 수 있습니까?
답변
ElasticSearch를 만든 사람으로서, 내가 왜 먼저 나아 갔는지에 대한 몇 가지 추론을 해줄 수있을 것입니다. :).
순수한 루센을 사용하는 것은 쉽지 않습니다. 실제로 성능을 높이고 라이브러리를 지원하려면 분산 지원이 필요하지 않으며 유지 관리 해야하는 임베디드 Java 라이브러리 일뿐입니다.
Lucene의 사용성 측면에서 (거의 6 년이 지난 지금) Compass를 만들었습니다. 그 목표는 Lucene 사용을 단순화하고 매일 Lucene을 더 단순하게 만드는 것이 었습니다. 내가 몇 번이고 왔던 것은 나침반을 배포 할 수 있어야한다는 것입니다. GigaSpaces, Coherence 및 Terracotta와 같은 데이터 그리드 솔루션과 통합하여 Compass에서 작업을 시작했지만 충분하지 않습니다.
기본적으로 분산 형 Lucene 솔루션을 샤딩해야합니다. 또한 유비쿼터스 API로 HTTP와 JSON이 발전함에 따라 언어가 다른 여러 시스템을 쉽게 사용할 수있는 솔루션을 의미합니다.
이것이 제가 계속해서 ElasticSearch를 만든 이유입니다. 이 모델은 고급 분산 모델을 갖추고 있으며 기본적으로 JSON을 말하며 JSON DSL을 통해 완벽하게 표현되는 많은 고급 검색 기능을 제공합니다.
Solr은 HTTP를 통해 인덱싱 / 검색 서버를 노출하기위한 솔루션이지만 ElasticSearch 는 훨씬 뛰어난 분산 모델과 사용 편의성을 제공 한다고 주장합니다 (현재 일부 검색 기능에는 부족하지만 오래 지속되지는 않지만) 계획은 모든 나침반 기능을 ElasticSearch로 가져 오는 것입니다). 물론 ElasticSearch를 만들었으므로 편견이 있으므로 직접 확인해야 할 수도 있습니다.
스핑크스에 관해서는 사용하지 않았으므로 언급 할 수 없습니다. 내가 참고할 수있는 것은 Sphinx 포럼의이 스레드에 대한 것으로, ElasticSearch의 우수한 분산 모델을 증명한다고 생각합니다.
물론 ElasticSearch는 단순히 배포하는 것보다 더 많은 기능을 가지고 있습니다. 실제로 클라우드를 염두에두고 구축되었습니다. 사이트에서 기능 목록을 확인할 수 있습니다.
답변
Sphinx, Solr 및 Elasticsearch를 사용했습니다. Solr / Elasticsearch는 Lucene 위에 구축됩니다. 웹 서버 API, 패싯, 캐싱 등 많은 공통 기능을 추가합니다.
간단한 전체 텍스트 검색 설정을 원한다면 Sphinx가 더 좋습니다.
검색을 사용자 정의하려면 Elasticsearch 및 Solr이 더 나은 선택입니다. 확장 성이 매우 뛰어납니다. 결과 점수를 조정하기 위해 자체 플러그인을 작성할 수 있습니다.
사용법 예 :
- 스핑크스 : craigslist.org
- Solr : Cnet, Netflix, digg.com
- 탄력적 검색 : Foursquare, Github
답변
Lucene은 정기적으로 수천만 개의 문서를 색인화하고 검색합니다. 검색이 빠르며 시간이 오래 걸리지 않는 증분 업데이트를 사용합니다. 여기까지 시간이 걸렸습니다. Lucene의 장점은 확장 성, 다양한 기능 및 적극적인 개발자 커뮤니티입니다. 베어 Lucene을 사용하려면 Java로 프로그래밍해야합니다.
새로 시작하는 경우 Lucene 제품군의 도구는 Solr 이며, 이는 Luce 보다 노출이 훨씬 쉽고 Lucene의 모든 기능을 갖추고 있습니다. 데이터베이스 문서를 쉽게 가져올 수 있습니다. Solr은 Java로 작성되므로 Solr을 수정하려면 Java 지식이 필요하지만 구성 파일을 조정하여 많은 작업을 수행 할 수 있습니다.
또한 MySQL 데이터베이스와 관련하여 Sphinx에 대한 좋은 소식을 들었습니다. 그래도 사용하지 않았습니다.
IMO는 다음에 따라 선택해야합니다.
- 필요한 기능 – 예를 들어 프랑스 형태소 분석기가 필요하십니까? Lucene과 Solr에는 하나가 있으며 다른 것에 대해서는 모른다.
- 구현 언어 능력-Java를 모르면 Java Lucene을 만지지 마십시오. 스핑크스로 작업하려면 C ++이 필요할 수 있습니다. Lucene도 다른 언어 로 포팅되었습니다 . 검색 엔진을 확장하려는 경우에 가장 중요합니다.
- 간편한 실험-Solr이이 측면에서 최고라고 생각합니다.
- 다른 소프트웨어와의 인터페이스-Sphinx는 MySQL과의 인터페이스가 우수합니다. Solr은 RESTful 서버로 루비, XML 및 JSON 인터페이스를 지원합니다. Lucene은 Java를 통한 프로그래밍 방식의 액세스 만 제공합니다. Compass 와 Hibernate Search 는 더 큰 프레임 워크에 통합 된 Lucene의 래퍼입니다.
답변
10.000.000 이상의 MySql 레코드와 10 가지 이상의 데이터베이스가있는 세로 검색 프로젝트에서 Sphinx를 사용합니다. MySQL에 대한 탁월한 지원과 인덱싱 성능이 뛰어나고 연구는 빠르지 만 Lucene보다 약간 적습니다. 그러나 매일 빠르게 색인을 생성하고 MySQL DB를 사용하려면 올바른 선택입니다.
답변
ElasticSearch와 Solr 을 비교 하는 실험
답변
내 스핑크스 .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)