'elasticsearch'에 해당되는 글 420건

  1. 2013.04.23 [Elasticsearch] Cluster 설정 중 rack 과 zone 알아보기.
  2. 2013.04.19 [Elasticsearch] node 별 색인 shard 와 replicas flow.
  3. 2013.04.19 [Elasticsearch] Plugins - site 플러그인과 custom analyzer 플러그인 만들기 1
  4. 2013.04.18 [Elasticsearch] Query DSL - Filters
  5. 2013.04.17 [Elasticsearch] Query DSL
  6. 2013.04.17 [Elasticsearch] Indices API - Cluster ....
  7. 2013.04.17 [elasticsearch] Indices API - Warmers
  8. 2013.04.17 [Elasticsearch] 불일치 데이터 검증 툴
  9. 2013.04.17 [elasticsearch] Indices API - Snapshot
  10. 2013.04.17 [elasticsearch] Indices API - Optimize

[Elasticsearch] Cluster 설정 중 rack 과 zone 알아보기.

Elastic/Elasticsearch 2013. 4. 23. 16:36

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/modules/cluster/


cluster 세팅 중 위 문서에 아래와 같은 설정이 있습니다.

Shard Allocation Awareness

sharding 과 replica 설정에 따라 clustering 환경에서 어떻게 배치 시킬것인지 관리 할 수 있도록 해주는 추가 설정 입니다.

즉, 특정 노드로 shard 를 배치 시키거나 replica 가 되도록 합니다.


아래는 이해를 돕기 위한 설정 예제 입니다.


[Rack 설정 예제]

- 1 cluster, 4 nodes


[node 공통]

cluster.name: cluster_a

cluster.routing.allocation.awareness.attributes: rack_id


[node 1]

  node.rack_id: rack_1

  node.name: node_1


[node 2]

  node.rack_id: rack_2

  node.name: node_2


[node 3]

  node.rack_id: rack_1

  node.name: node_3


[node 4]

  node.rack_id: rack_2

  node.name: node_4


[Zone 설정 예제]

- 1 cluster, 2 nodes


[node 공통]

cluster.name: cluster_a

cluster.routing.allocation.awareness.force.zone.values: zone_1, zone_2

cluster.routing.allocation.awareness.attributes: zone


[node 1]

  node.zone: zone_1

  node.name: node_1


[node 2]

  node.zone: zone_1

  node.name: node_2



Rack 의 경우 서로 다른 Rack 위치한 node 들에 대한 분산설정으로 같은 IDC 내 서로 다른 rack 이나 IDC 간 HA 구성이 가능 합니다.

 Zone 의 경우 특정 zone 으로 동일 데이터가 몰려 SPOF 를 예방하기 위한 구성으로 사용이 가능 합니다.


직접 해보시면 쉽게 이해가 됩니다. :)

:

[Elasticsearch] node 별 색인 shard 와 replicas flow.

Elastic/Elasticsearch 2013. 4. 19. 16:27

쉽게 개념을 잡기 위해 Document 색인 요청 시 어떤 flow 로 색인 및 복제를 하는지 간단하게 표현해 봤습니다.


  

 
Find Primary Shard






                                    ↓


 
Perform Index into the Primary Shard






                                    ↓


 
Perform Replica to another Node (using async)



:

[Elasticsearch] Plugins - site 플러그인과 custom analyzer 플러그인 만들기

Elastic/Elasticsearch 2013. 4. 19. 10:55

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/modules/plugins/


elasticsearch를 사용하면서 가장 많이 사용하는 것이 head 와 kr lucene 형태소 분석기가 아닌가 싶습니다.

그럼 이런 것들은 어떻게 제작을 해야 하는지 궁금 할텐데요.

위 원문 아래쪽에 제공되는 모든 plugin 목록을 보여 주고 있습니다.

또는 아래 링크에서도 확인이 가능 합니다.


[git]

- https://github.com/elasticsearch

- https://github.com/search?q=elasticsearch&type=&ref=simplesearch


우선 head와 같은 site plugin 구성 부터 살펴 보겠습니다.

이건 사실 설명이 필요 없습니다. ^^;;


[_site plugin]

- plugin location : ES_HOME/plugins

- site plugin name : helloworld

- helloworld site plugin location : ES_HOME/plugins/helloworld

    . helloworld 폴더 아래로 _site 폴더 생성

    . _site 폴더 아래로 구현한 html, js, css 등의 파일을 위치 시키고 아래 링크로 확인 하면 됩니다.

- helloworld site plugin url

    . http://localhost:9200/_plugin/helloworld/index.html

- elasticsearch server 와의 통신은 ajax 통신을 이용해서 필요한 기능들을 구현 하시면 됩니다.


[kr lucene analyzer plugin] 

- 이미 관련 plugin 은 제공 되고 있습니다.

- 아래 링크 참고

http://cafe.naver.com/korlucene

https://github.com/chanil1218/elasticsearch-analysis-korean

- 적용하는 방법은 두 가지 입니다.

    . First : elasticsearch-analysis-korean 을 설치 한다. (설치 시 es 버전을 맞춰 주기 위해서 별도 빌드가 필요 할 수도 있다.)

    . Second : lucene kr analyzer 라이브러리를 이용해서 plugin 형태로 제작해서 설치 한다.

- 아래는 plugin  형태로 제작해서 설치한 방법을 기술 한 것입니다.

분석기 라이브러리를 사용하는 경우 kimchy 가 만들어 놓은 코드를 기본 템플릿으로 사용해서 구현 하시면 쉽고 빠르게 적용 하실 수 있습니다.

https://github.com/elasticsearch/elasticsearch-analysis-smartcn


- 만들어 봅시다.

[프로젝트 구성]

- Eclipse 에서 Maven 프로젝트를 하나 생성 합니다.


[패키지 및 리소스 구성]

- org.elasticsearch.index.analysis

    . KrLuceneAnalysisBinderProcessor.java

public class KrLuceneAnalysisBinderProcessor extends AnalysisModule.AnalysisBinderProcessor {


    @Override

    public void processAnalyzers(AnalyzersBindings analyzersBindings) {

        analyzersBindings.processAnalyzer("krlucene_analyzer", KrLuceneAnalyzerProvider.class);

    }


    @Override

    public void processTokenizers(TokenizersBindings tokenizersBindings) {

        tokenizersBindings.processTokenizer("krlucene_tokenizer", KrLuceneTokenizerFactory.class);

    }


    @Override

    public void processTokenFilters(TokenFiltersBindings tokenFiltersBindings) {

        tokenFiltersBindings.processTokenFilter("krlucene_filter", KrLuceneTokenFilterFactory.class);

    }

}

    . 이 클래스는 analyzer, tokenizer, filter 를 name 기반으로 등록해 준다.

    . settings 구성 시 analyzer, tokenizer, filter 에 명시 하는 name 부분에 해당한다.

    . settings 에서 type 부분에는 패키지 full path 를 명시 하면 된다.

curl -XPUT http://localhost:9200/test  -d '{

    "settings" : { 

        "index": {

            "analysis": {

                "analyzer": {

                    "krlucene_analyzer": {

                        "type": "org.elasticsearch.index.analysis.KrLuceneAnalyzerProvider",

                        "tokenizer" : "krlucene_tokenizer",

                        "filter" : ["trim","lowercase", "krlucene_filter"]

                    }   

                }   

            }   

        }   

    }   

}'


    . KrLuceneAnalyzerProvider.java

public class KrLuceneAnalyzerProvider extends AbstractIndexAnalyzerProvider<KoreanAnalyzer> {


    private final KoreanAnalyzer analyzer;


    @Inject

    public KrLuceneAnalyzerProvider(Index index, @IndexSettings Settings indexSettings, Environment env, @Assisted String name, @Assisted Settings settings) throws IOException {

        super(index, indexSettings, name, settings);


        analyzer = new KoreanAnalyzer(Lucene.VERSION.LUCENE_36);

    }


    @Override

    public KoreanAnalyzer get() {

        return this.analyzer;

    }

}


    . KrLuceneTokenFilterFactory.java

public class KrLuceneTokenFilterFactory extends AbstractTokenFilterFactory {


    @Inject

    public KrLuceneTokenFilterFactory(Index index, @IndexSettings Settings indexSettings, @Assisted String name, @Assisted Settings settings) {

        super(index, indexSettings, name, settings);

    }


    @Override

    public TokenStream create(TokenStream tokenStream) {

        return new KoreanFilter(tokenStream);

    }

}


    . KrLuceneTokenizerFactory.java

public class KrLuceneTokenizerFactory extends AbstractTokenizerFactory {


    @Inject

    public KrLuceneTokenizerFactory(Index index, @IndexSettings Settings indexSettings, @Assisted String name, @Assisted Settings settings) {

        super(index, indexSettings, name, settings);

    }


    @Override

    public Tokenizer create(Reader reader) {

        return new KoreanTokenizer(Lucene.VERSION.LUCENE_36, reader);

    }

}


- org.elasticsearch.plugin.analysis.krlucene

    . AnalysisKrLucenePlugin.java

    . 이 클래스는 생성한 plugin 을 es 에 등록해 주는 역할을 한다.

    . plugin 명을 analysis-krlucene 라고 했을 경우 아래와 같은 path 에 jar 파일을 위치 시켜야 합니다.

    ES_HOME/plugins/analysis-krlucene


- src/main/assemblies/plugin.xml

<?xml version="1.0"?>

<assembly>

    <id>plugin</id>

    <formats>

        <format>zip</format>

    </formats>

    <includeBaseDirectory>false</includeBaseDirectory>

    <dependencySets>

        <dependencySet>

            <outputDirectory>/</outputDirectory>

            <useProjectArtifact>true</useProjectArtifact>

            <useTransitiveFiltering>true</useTransitiveFiltering>

            <excludes>

                <exclude>org.elasticsearch:elasticsearch</exclude>

            </excludes>

        </dependencySet>

        <dependencySet>

            <outputDirectory>/</outputDirectory>

            <useProjectArtifact>true</useProjectArtifact>

            <scope>provided</scope>

        </dependencySet>

    </dependencySets>

</assembly>


- src/main/resources/es-plugin.properties

plugin=org.elasticsearch.plugin.analysis.krlucene.AnalysisKrLucenePlugin


- 이렇게 해서 빌드를 하시고 생성된 jar 파일을 위에서 언급한 경로에 위치 시키고 ES 재시작 후 아래와 같이 테스트 해보시면 됩니다.


[테스트]

- test 인덱스 생성 (위에 생성 코드 참고)

- 테스트 URL

    . http://localhost:9200/test/_analyze?analyzer=krlucene_analyzer&text=이것은 루씬한국어 형태소 분석기 플러그인 입니다.&pretty=1

{
  "tokens" : [ {
    "token" : "이것은",
    "start_offset" : 0,
    "end_offset" : 3,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "이것",
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 2
  }, {
    "token" : "루씬한국어",
    "start_offset" : 4,
    "end_offset" : 9,
    "type" : "word",
    "position" : 3
  }, {
    "token" : "루씬",
    "start_offset" : 4,
    "end_offset" : 6,
    "type" : "word",
    "position" : 4
  }, {
    "token" : "한국어",
    "start_offset" : 6,
    "end_offset" : 9,
    "type" : "word",
    "position" : 5
  }, {
    "token" : "형태소",
    "start_offset" : 10,
    "end_offset" : 13,
    "type" : "word",
    "position" : 6
  }, {
    "token" : "분석기",
    "start_offset" : 14,
    "end_offset" : 17,
    "type" : "word",
    "position" : 7
  }, {
    "token" : "분석",
    "start_offset" : 14,
    "end_offset" : 16,
    "type" : "word",
    "position" : 8
  }, {
    "token" : "플러그인",
    "start_offset" : 18,
    "end_offset" : 22,
    "type" : "word",
    "position" : 9
  }, {
    "token" : "플러그",
    "start_offset" : 18,
    "end_offset" : 21,
    "type" : "word",
    "position" : 10
  }, {
    "token" : "입니다",
    "start_offset" : 23,
    "end_offset" : 26,
    "type" : "word",
    "position" : 11
  }, {
    "token" : "입니",
    "start_offset" : 23,
    "end_offset" : 25,
    "type" : "word",
    "position" : 12
  } ] 

}


※ lucene 버전을 3.x 에서 4.x 로 올리고 싶으시다면 직접 코드 수정을 통해서 진행을 하시면 됩니다.

- elasticsearch-analysis-korean 의 경우는 고쳐야 할 부분이 좀 됩니다.

    . 우선 루씬 한국어 형태소 소스코드를 3.x 에서 4.x 로 올리셔야 합니다.

    . 관련 코드는 루씬 한국어 형태소 분석기 카페에 들어가 보시면 cvs 링크가 있습니다.

:pserver:anonymous@lucenekorean.cvs.sourceforge.net:/cvsroot/lucenekorean

    . 추가로 es 버전도 올리고 싶으시다면 pom.xml 에서 코드를 수정해 주시기 바랍니다.

<properties>

    <elasticsearch.version>0.20.4</elasticsearch.version>

    <lucene.version>3.6.2</lucene.version>

</properties>


- 직접 플러그인을 생성해서 적용하는 방법은 위와 같이 플러그인을 만드시고 루씬한국어 형태소 분석기 라이브러리만 버전에 맞게 넣어서 사용하시면 됩니다.

    . 단, 플러그인의 pom.xml 에서 각 라이브러리의 version 은 맞춰 주셔야 겠죠.


:

[Elasticsearch] Query DSL - Filters

Elastic/Elasticsearch 2013. 4. 18. 10:46

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/query-dsl/

- 많이 사용되는 것들로 진행 합니다.



 

Queries

Filters

 


















[Filters]

기본적으로 filtered query 에서 동작 방식을 소개 했기 때문에 이 점을 이해하고 보셔야 합니다.


[and/or]

- 쿼리 결과에 대한 추가 쿼리의 and/or 연산을 수행 합니다.

- 쿼리 결과를 cache 하고 싶을 경우 _cache:true 설정을 하면 됩니다.


[bool]

- boolean 쿼리를 추가 수행 합니다.


[exists]

- 결과에 대해서 항상 cache 합니다.


[ids]

- ids 를 포함한 문서를 필터 합니다.


[limit]

- shard 당 문서 수를 제한 합니다.


[type]

- document/mapping type 에 대한 filter 합니다.


[missing]

- 문서의 특정 필드 값이 no value 인 것을 filter 합니다.

- 지정된 field 는 null_value 를 갖습니다.

- 예제가 직관적이기 떄문에 추가 합니다.

{
    "constant_score" : {
        "filter" : {
            "missing" : { 
                "field" : "user",
                "existence" : true,
                "null_value" : true
            }
        }
    }
}


[not]

- 질의된 결과에 대해서 추가로 주어진 not filter 로 match 된 문서를 제외 합니다.


[numeric range]

- range filter와 유사하며, 어떤 수의 범위를 갖습니다.

- 주어진 parameters 는 아래와 같습니다.

NameDescription
fromThe lower bound. Defaults to start from the first.
toThe upper bound. Defaults to unbounded.
include_lowerShould the first from (if set) be inclusive or not. Defaults to true
include_upperShould the last to (if set) be inclusive or not. Defaults to true.
gtSame as setting from and include_lower to false.
gteSame as setting from and include_lower to true.
ltSame as setting to and include_upper to false.
lteSame as setting to and include_upper to true.

[prefix]

- phrase query 와 유사하며,  prefix query 참고


[query]

- 추가 query 를 생성 할 수 있습니다.


[range]

- range query 참고


[script]

- script 를 이용한 filter 를 적용 할 수 있습니다.


[term]

- term query 참고


[terms]

- terms query 참고

- execution mode 를 지원 합니다.

- 기본 plain 그리고 bool, and, or 지원


[nested]

- nested query 참고


※ filter 의 경우 기본 query 에서 제공 하는 것과 거의 동일 하며,

이 API 의 목적은 한번 질의한 결과에 대해 별도의 filtering 을 하기 위함 입니다.


:

[Elasticsearch] Query DSL

Elastic/Elasticsearch 2013. 4. 17. 17:41

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/query-dsl/

- 많이 사용되는 것들로 진행 합니다.



 

Queries

Filters

 


















[Query]

[match]

- 기본 boolean type 과 or 연산


[multi match]

- 여러개의 field 에 대한 match query

-field 선언 시 boosting 옵션 추가 (^2 라는 의미는 2배 더 중요하다는 의미)


[bool]

- must : 문서에 매칭 되는 것이 무조건 나타나야 함.

- should : minimum_number_should_match 값을 통해서 문서에 매칭 되는 것이 나타나야 함.

- must_not : 문서에 매칭 정보가 있으면 안됨. (exclusive)


[boosting]

- query 의 결과를 효과적으로 감소 시킬 수 있다.

- 원문 예제가 이해하는데 직관적이라 추가 합니다.

{ "boosting" : { "positive" : { "term" : { "field1" : "value1" } }, "negative" : { "term" : { "field2" : "value2" } }, "negative_boost" : 0.2 }

}

- negative 조건에 따라 원하지 않는 문서에 대한 스코어를 떨어 트릴수 있습니다.


[constant_score]

- query 된 모든 문서의 score 를 동일하게 한다.


[dis_max]

- multi_field 에 단어 검색 시 유용하다.

- multiple field 에 같은 term 을 포함 하고 있을 경우 tie_breaker 값으로 더 좋은 결과 판정을 합니다.

- explain 을 떠보면서 검색 결과에 따른 score 변화를 확인해 보는게 좋을 것 같내요.


[field]

- query_string 버전의 단순화 query 이며, 대부분의 parameter 를 사용할 수 있습니다.


[filtered]

- query 결과에 대한 filter 를 적용 합니다.

- 예제가 직관적이라 추가 합니다.

{ "filtered" : { "query" : { "term" : { "tag" : "wow" } }, "filter" : { "range" : { "age" : { "from" : 10, "to" : 20 } } } }

}


[flt : fuzzy like this][flt_field]

- 지정한 field 들에 대해서 like 검색을 지원 합니다.

_ _field 가 들어 간 것은 아래 파라미터 중 fields 만 없습니다.

ParameterDescription
fieldsA list of the fields to run the more like this query against. Defaults to the _all field.
like_textThe text to find documents like it, required.
ignore_tfShould term frequency be ignored. Defaults to false.
max_query_termsThe maximum number of query terms that will be included in any generated query. Defaults to 25.
min_similarityThe minimum similarity of the term variants. Defaults to 0.5.
prefix_lengthLength of required common prefix on variant terms. Defaults to 0.
boostSets the boost value of the query. Defaults to 1.0.
analyzerThe analyzer that will be used to analyze the text. Defaults to the analyzer associated with the field.


[fuzzy]

- Levenshtein algorithm 을 기반으로 하는 유사도 검색을 지원 한다.


[match_all]

- 모든 문서를 출력한다.


[mlt : more like this][mlt_field]

- 지정한 field 들에 대해서 like 검색을 지원 합니다.

- term 단위 like 검색이라는 것을 유의 해야함.

- 결국 지정된 field 에는 term_vector 설정이 되어 있어야 함

ParameterDescription
fieldsA list of the fields to run the more like this query against. Defaults to the _all field.
like_textThe text to find documents like it, required.
percent_terms_to_matchThe percentage of terms to match on (float value). Defaults to 0.3 (30 percent).
min_term_freqThe frequency below which terms will be ignored in the source doc. The default frequency is 2.
max_query_termsThe maximum number of query terms that will be included in any generated query. Defaults to 25.
stop_wordsAn array of stop words. Any word in this set is considered “uninteresting” and ignored. Even if your Analyzer allows stopwords, you might want to tell the MoreLikeThis code to ignore them, as for the purposes of document similarity it seems reasonable to assume that “a stop word is never interesting”.
min_doc_freqThe frequency at which words will be ignored which do not occur in at least this many docs. Defaults to 5.
max_doc_freqThe maximum frequency in which words may still appear. Words that appear in more than this many docs will be ignored. Defaults to unbounded.
min_word_lenThe minimum word length below which words will be ignored. Defaults to 0.
max_word_lenThe maximum word length above which words will be ignored. Defaults to unbounded (0).
boost_termsSets the boost factor to use when boosting terms. Defaults to 1.
boostSets the boost value of the query. Defaults to 1.0.
analyzerThe analyzer that will be used to analyze the text. Defaults to the analyzer associated with the field.

[prefix]

- 매치된 문서는 prefix를 포함한 term 을 갖는다. (not_analyzed)


[query_string]

- query parser 를 이용해서 검색 함.

ParameterDescription
queryThe actual query to be parsed.
default_fieldThe default field for query terms if no prefix field is specified. Defaults to the index.query.default_field index settings, which in turn defaults to _all.
default_operatorThe default operator used if no explicit operator is specified. For example, with a default operator of OR, the query capital of Hungary is translated to capital OR of OR Hungary, and with default operator of AND, the same query is translated to capital AND of AND Hungary. The default value is OR.
analyzerThe analyzer name used to analyze the query string.
allow_leading_wildcardWhen set, * or ? are allowed as the first character. Defaults to true.
lowercase_expanded_termsWhether terms of wildcard, prefix, fuzzy, and range queries are to be automatically lower-cased or not (since they are not analyzed). Default it true.
enable_position_incrementsSet to true to enable position increments in result queries. Defaults to true.
fuzzy_max_expansionsControls the number of terms fuzzy queries will expand to. Defaults to 50
fuzzy_min_simSet the minimum similarity for fuzzy queries. Defaults to 0.5
fuzzy_prefix_lengthSet the prefix length for fuzzy queries. Default is 0.
phrase_slopSets the default slop for phrases. If zero, then exact phrase matches are required. Default value is 0.
boostSets the boost value of the query. Defaults to 1.0.
analyze_wildcardBy default, wildcards terms in a query string are not analyzed. By setting this value to true, a best effort will be made to analyze those as well.
auto_generate_phrase_queriesDefault to false.
minimum_should_matchA percent value (for example 20%) controlling how many “should” clauses in the resulting boolean query should match.
lenientIf set to true will cause format based failures (like providing text to a numeric field) to be ignored. (since 0.19.4).

ParameterDescription
use_dis_maxShould the queries be combined using dis_max (set it to true), or a bool query (set it to false). Defaults to true.
tie_breakerWhen using dis_max, the disjunction max tie breaker. Defaults to 0.

[range]

- string 은 TermRangeQuery

- numeric/date 는 NumericRangeQuery

NameDescription
fromThe lower bound. Defaults to start from the first.
toThe upper bound. Defaults to unbounded.
include_lowerShould the first from (if set) be inclusive or not. Defaults to true
include_upperShould the last to (if set) be inclusive or not. Defaults to true.
gtSame as setting from to the value, and include_lower to false.
gteSame as setting from to the value,and include_lower to true.
ltSame as setting to to the value, and include_upper to false.
lteSame as setting to to the value, and include_upper to true.
boostSets the boost value of the query. Defaults to 1.0.

[term]

- 어떤 term 을 포함한 결과를 갖는다. (term 은 not_analyzed)

- 결국 하나의 word 라고 보면 이해하는데 도움이 됨.


[terms]

- term query 의 IN 절 기능을 제공 한다.


[wildcard]

- * 과 ? 로 매칭을 할 수 있다.

- * 은 SQL 에서 % 와 비슷하며, ? 는 정규표현식의 single character 와 비슷하다.

- 사용 시 주의 할 점은 *, ? 를 첫 시작으로 사용하지 말라는 것이다.


[nested]

- nested mapping 된 parent 문서에 대한 검색을 지원 한다.

- 예제가 직관적이라 추가 합니다.

{
    "type1" : {
        "properties" : {
            "obj1" : {
                "type" : "nested"
            }
        }
    }
} 
{
    "nested" : {
        "path" : "obj1",
        "score_mode" : "avg",
        "query" : {
            "bool" : {
                "must" : [
                    {
                        "match" : {"obj1.name" : "blue"}
                    },
                    {
                        "range" : {"obj1.count" : {"gt" : 5}}
                    }
                ]
            }
        }
    }
}


[indices]

- multiple indices 로 검색을 수행 할 수 있다.

- 역시 예제가 직관적이라 추가 합니다.

{
    "indices" : {
        "indices" : ["index1", "index2"],
        "query" : {
            "term" : { "tag" : "wow" }
        },
        "no_match_query" : {
            "term" : { "tag" : "kow" }
        }
    }
}

- no_match_query 에 none 을 set 하면 no document, all 을 set 하면 match_all 이 된다.



※ Queries 가 너무 많아서 Filters 는 별도로 분리 합니다.


:

[Elasticsearch] Indices API - Cluster ....

Elastic/Elasticsearch 2013. 4. 17. 14:58

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-cluster-*


cluster 관련 API 는 워낙 원문이 쉽고 직관적으로 잘 되어 있어서 따로 정리 하지 않습니다.

아래 링크들을 참고 하시기 바랍니다.


Cluster

:

[elasticsearch] Indices API - Warmers

Elastic/Elasticsearch 2013. 4. 17. 14:52

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-warmers/



이 API 는 대량 검색 즉, facet, sorting 시 설정 할 경우 성능 향상 효과가 있으며, bulk indexing 시에는 disable 하는 것이 성능에 좋습니다.

자세한 내용은 원문 참고 바랍니다.

:

[Elasticsearch] 불일치 데이터 검증 툴

Elastic/Elasticsearch 2013. 4. 17. 14:41

원문 : https://github.com/Aconex/scrutineer


 README.md

Analyses a secondary stream of information against a known point-of-truth and reports inconsistencies.

The Why

When you have a Lucene-based index of substantial size, say many hundreds of millions of records, what you want is confidence that your index is correct. In many cases, people use Solr/ElasticSearch/Compass to index their central database, mongodb, hbase etc so the index is a secondary storage of data.

How do you know if your index is accurate? Can you just reindex 500 million documents anytime you like? (That's the Aliens: "Nuke the site from Orbit... It's the only way to be sure" approach). No, if there ARE inconsistencies in your index, then you want to:

  • find the items that are incorrect (and only them)
  • do it fast

Scrutineer has been designed with this in mind, it can find any inconsistencies in your index fast.

How does this work?

Scrutineer relies on your data having 2 core properties:

  • an ID - a unique identifier for your object
  • a Version - something stored in your primary datastore for that object that represents the temporal state of that object

The Version property is commonly used in an Optimistic Locking pattern. If you store the ID & Version information in your secondary store (say, Solr/ElasticSearch) then you can always compare for any given item whether the version in secondary store is up to date.

Scrutineer takes a stream from your primary, and a stream from your secondary store, presumes they are sorted identically (more on that later) and walks the streams doing a merge comparison. It detects 4 states:

  1. Both items are identical (yay!)
  2. An ID is missing from the secondary stream (A missed add? maybe that index message you sent to Solr/ElasticSearch never made it, anyway, it's not there)
  3. An ID was detected in the secondary, but wasn't in the primary stream (A missed delete? something was deleted on the primary, but the secondary never got the memo)
  4. The ID exists in both streams, but the Version values are inconsistent (A missed update? similar to the missed add, this time perhaps an update to a row in your DB never made it to Solr/ElasticSearch)

Example

Here's an example, 2 streams in sorted order, one from the Database (your point-of-truth), and one from ElasticSearch (the one you're checking) with the : for each side:

DatabaseElasticSearch
1:123451:12345
2:234553:84757
3:847574:98765
4:987655:38475
6:346666:34556

Scrutineer picks up that:

  • ID '2' is missing from ElasticSearch
  • ID '5' was deleted from the database at some point, but ElasticSearch still has it in there
  • ID '6' is visible in ElasticSearch but appears to have the wrong version

Running Scrutineer

The very first thing you'll need to do is get your JDBC Driver jar and place it in the 'lib' directory of the unpacked package. We already have a JTDS driver in there if you're using SQL Server (that's just what we use).

bin/scrutineer \
            --jdbcURL=jdbc:jtds:sqlserver://mydbhost/mydb  \
            --jdbcDriverClass=net.sourceforge.jtds.jdbc.Driver \
            --jdbcUser=itasecret \
            --jdbcPassword=itsasecret   \
            --sql="select id,version from myobjecttype order by cast(id as varchar(100))" \
            --clusterName=mycluster \
            --indexName=myindex \
            --query="_type:myobjecttype" \
            --numeric

Note: if you're weirded out about that '...cast(...)' then don't worry, we'll explain that shortly.

  • jdbcURL – Standard JDBC URL you would use for your app to connect to your database
  • jdbcDriverClass - Fully qualified class name of your JDBC Driver (don't forget to put your JDBC Driver jar in the lib directory as said above!)
  • jdbcUser - user account to access your JDBC Database
  • jdbcPassword -- password required for the user credentials
  • sql - The SQL used to generate a lexicographical stream of ID & Version values (in that column order)
  • clusterName - this is your ElasticSearch cluster name used to autodetect and connect to a node in your cluster
  • indexName - the name of the index on your ElasticSearch cluster
  • query - A query_parser compatible search query that returns all documents in your ElasticSearch index relating to the SQL query you're using Since it is common for an index to contain a type-per-db-table you can use the "_type:" search query to filter for all values for that type.
  • numeric - use this if your query returns results numerically ordered

Output

Scrutineer writes any inconsistencies direct to Standard Error, in a well-defined, tab-separated format for easy parsing to feed into a system to reindex/cleanup. If we use the Example scenario above, this is what Scrutineer would print out:

NOTINSECONDARY    2    23455
MISMATCH    6    34666    secondaryVersion=34556
NOTINPRIMARY    5    38475

The general format is:

FailureType\t**ID**\t**VERSION**\t**Optional:Additional Info**

NOTINSECONDARY

This means you are missing this item in your secondary and you should reindex/re-add to your secondary stream

MISMATCH

This means the version of the object stored in the secondary is not the same information as the primary, and you should reindex

NOTINPRIMARY

The object was removed from the Primary store, but the secondary still has it. You should remove this item from your secondary.

Scrutineer does not report when items match, we'll presume you're just fine with that...

Memory

By default, Scrutineer allocates 256m to the Java Heap, which is used for sort, and ElasticSearch result buffers. This should be more than enough for the majority of cases but if you find you get an OutOfMemoryError, you can override the JAVA_OPTS environment variable to provide more heap. e.g.

export JAVA_OPTS=-Xmx1048m

Sorting

VERY IMPORTANT: Scrutineer relies on both streams to be sorted using an identical mechanism. It requires input streams to be in lexicographical (default) or numerical (indicate using --numeric) sort order.

ElasticSearch

Since Aconex uses ElasticSearch, Scrutineer supports ES out of the box, but it would not be difficult for others to integrate a Solr stream and wire something up. Happy to take Pull Requests!

What are the 'best practices' for using Scrutineer?

The authors of Scrutineer, Aconex, index content from a JDBC data source and index using ElasticSearch. We do the following:

  • In the database table of the object being indexed we add an Insert/Update trigger to populate a 'lastupdated' timestamp column as our Version property
  • When we index into ElasticSearch, we set the Version property of the item using the VersionType.EXTERNAL setting.
  • We create an SQL Index on this tuple so these 2 fields can be retrieved from the database very fast

Assumptions

  • Your Version property is Long compatible. You can use java.sqlTimestamps column types too as a Version (that's what we do)
  • Aconex is DB->ElasticSearch centric at the moment. We've tried to keep things loosely coupled, so it should be simple to add further integration points for other Primary & Secondary sources (HBase, MongoDB, Solr).

JDBC Drivers

Scrutineer ships with the SQL Server JTDS driver by default (it's what we use). All you should need to do is drop your own JDBC driver in the 'repo' sub-directory of the Scrutineer distribution (where all the other jars are). We use the Maven AppAssembler plugin which is configured to automatically load all JARs in this path onto the classpath.

Building

Scrutineer is a Maven project, which really should just build right out of the box if you have Maven installed. Just type:

mvn package

And you should have a Tarball in the 'target' sub-directory.

Submitting Pull Requests

First, Please add unit tests!

Second, Please add integration tests!

Third, We have tightened up the quality rule set for CheckStyle, PMD etc pretty hard. Before you issue a pull request, please run:

mvn verify

which will run all quality checks. Sorry to be super-anal, but we just like Clean Code.

Roadmap

  • Scrutineer currently only runs in a single thread based on a single stream.
    It would be good to provide a 'manifest' to Scrutineer to outline a set of stream verifications to perform, perhaps one for each type you have so that your multi-core system can perform multiple stream comparisons in parallel.

  • Incremental checking – Right now Scrutineer checks the whole thing, BUT if you are using timestamp-based versions, there's no reason it couldn't only check objects that were changed after the last known full verification. This would require one to keep track of deletes on the primary stream (perhaps an OnDelete Trigger in your SQL database) so that IDs that were deleted in the primary stream after the last full check could be detected correctly.

  • Obviously we'd love to have a Solr implementation here, we hope the community can help here.

:

[elasticsearch] Indices API - Snapshot

Elastic/Elasticsearch 2013. 4. 17. 14:40

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-gateway-snapshot/


이 API 는 shared storage gateway 에서 동작 합니다.

local storage gateway 에서는 필요 하지 않다는 점을 유의 하시기 바랍니다.


- snapshot 정보는 shared storage location 에 저장 됩니다.


아래는 간단한 Java Code 예제 입니다.


[Java 예제]

request.indices("blog")

.operationThreading(BroadcastOperationThreading.THREAD_PER_SHARD);


response = indices.gatewaySnapshot(request).actionGet();


log.debug("{}", response.getSuccessfulShards());

:

[elasticsearch] Indices API - Optimize

Elastic/Elasticsearch 2013. 4. 17. 12:52

본 문서는 개인적인 테스트와 elasticsearch.org 그리고 community 등을 참고해서 작성된 것이며,

정보 교환이 목적입니다.


잘못된 부분에 대해서는 지적 부탁 드립니다.

(예시 코드는 성능 및 보안 검증이 되지 않았습니다.)



[elasticsearch API 리뷰]

원문 링크 : http://www.elasticsearch.org/guide/reference/api/admin-indices-optimize/


이 API 는 indices 를 최적화 시킨다.

검색 시 성능 향상을 가져 옴.


아래는 원문의 Request Parameters 이다.

Request Parameters

The optimize API accepts the following request parameters:

NameDescription
max_num_segmentsThe number of segments to optimize to. To fully optimize the index, set it to 1. Defaults to simply checking if a merge needs to execute, and if so, executes it.
only_expunge_deletesShould the optimize process only expunge segments with deletes in it. In Lucene, a document is not deleted from a segment, just marked as deleted. During a merge process of segments, a new segment is created that does not have those deletes. This flag allow to only merge segments that have deletes. Defaults to false.
refreshShould a refresh be performed after the optimize. Defaults to true.
flushShould a flush be performed after the optimize. Defaults to true.
wait_for_mergeShould the request wait for the merge to end. Defaults to true. Note, a merge can potentially be a very heavy operation, so it might make sense to run it set to false.

- 설명이 잘나와 있어서 요약만 합니다.

- fully optimize 를 위해서는 max_num_segments : 1

- only_expunge_deletes 가 true 이면 삭제 마킹만

- wait_for_merge false 를 이용해서 대용량 처리


파라미터를 이용한 샘플 코드를 보기로 하겠습니다.


[Java 예제코드]

response = builder.setIndices("blog")

.setMaxNumSegments(1) // full optimize 를 위해서는 1, 기본은 설정을 하지 않으면 simply checking 을 

.setOnlyExpungeDeletes(false) // 기본 false

.setWaitForMerge(true)

.setOperationThreading(BroadcastOperationThreading.THREAD_PER_SHARD)

.execute()

.actionGet();

log.debug("{}", response.getSuccessfulShards());


OptimizeRequest 와 OptimizeRequestBuilder 이 두가지를 이용해서 구현 가능 함.


: