'Elastic/Elasticsearch'에 해당되는 글 385건

  1. 2022.11.23 [Elasticsearch] Accessing document field on scripts
  2. 2022.11.21 [Elasticsearch] Date Type 사용 시
  3. 2022.11.16 [Elasticsearch] Document Count 정보가 필요해.
  4. 2022.11.14 [Elasticsearch] Keword Field 내 Normalizer 선언 시 주의 사항.
  5. 2022.09.20 [Elasticsearch] Elasticsearch ES-Hadoop 내 Spark Bulk Request Error Handler 1
  6. 2022.07.20 [Elasticsearch] Arirang Plugin on Elasticsearch 8.3.2
  7. 2022.07.18 [Elasticsearch] Filter Aggregation 사용하기.
  8. 2022.07.18 [Elasticsearch] Common Options 활용
  9. 2022.07.14 [Elasticsearch] Text Analysis, Performance Aggs.
  10. 2022.07.14 [Elasticsearch] Index Template 사용 시 Mapping 정보 오류

[Elasticsearch] Accessing document field on scripts

Elastic/Elasticsearch 2022. 11. 23. 17:08

아는 것도 시간이 지나면 다 까먹는 나이!!

 

[레퍼런스]

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-fields.html#_search_and_aggregation_scripts
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-expression.html

 

접근 유형에 따른 성능)

doc value 가 가장 빠르고 _source 와 _fields 는 비슷 합니다.

 

QueryDSL 예제)

GET /kibana_sample_data_ecommerce/_search
{
  "query": {
    "script_score": {
      "query": {
        "bool": {
          "filter": {
            "term": {
              "products.product_name": "shirt"
            }
          }
        }
      },
      "script": {
          "lang": "expression",
          "source": "_score * doc['taxless_total_price']"
        }
    }
  }
}

GET /kibana_sample_data_ecommerce/_search
{
  "query": {
    "script_score": {
      "query": {
        "bool": {
          "filter": {
            "term": {
              "products.product_name": "shirt"
            }
          }
        }
      },
      "script": {
          "lang": "painless",
          "source": "_score * doc['taxless_total_price'].value"
        }
    }
  }
}

GET /kibana_sample_data_ecommerce/_search
{
  "query": {
    "script_score": {
      "query": {
        "bool": {
          "filter": {
            "term": {
              "products.product_name": "shirt"
            }
          }
        }
      },
      "script": {
          "lang": "painless",
          "source": "_score * params._source.taxless_total_price"
        }
    }
  }
}

expression 과 painless 에 따라 다르기 때문에 사용에 주의 하세요.

:

[Elasticsearch] Date Type 사용 시

Elastic/Elasticsearch 2022. 11. 21. 21:59

Elastic Stack 에서 Date Field Type 사용 시 내용을 인지 하고 사용 하셔야 데이터에 대해서 기대한 결과를 얻을 수 있습니다.

 

우선, Elasticsearch 는 기본 UTC 시간을 사용 합니다.

색인 되는 Date 값은 모두 UTC 로 저장 된다고 보시면 됩니다.

또한 기본 질의 시 사용 하는 값도 UTC 입니다.

 

하지만, Kibana 를 사용 하다 보면 UTC 에 대한 사용이 불편해서 브라우저 TZ 설정이나 사용자 정의 TZ 설정으로 Date 값을 사용 할 때가 있습니다.

이때 주의 해야 할 점은 실제 색인된 데이터에 대한 변형이나 조작이 있는게 아닌 Client 단에서 TZ 설정에 따른 질의 시 Date 값 변환이나 화면에서의 조작을 한다는 것을 알아야 합니다.

 

아래 설명은 그냥 저 혼자 기억하기 위해서 풀어 쓴걸 올려 둔 내용 입니다.

- kibana 에서는 실제 색인된 date 유형의 값에 대한 tz 설정으로 화면에서 변환 된 정보로 보여 주는 것이며,
실제 질의는 utc 데이터로 질의가 이루어 집니다.
  ㄴ 결국 query dsl 작성 시 utc 기준으로 작성이 되어야 하기 때문에
     본인이 속한 tz 값을 계산 해서 질의 값에 반영이 되어야 합니다.
  ㄴ 단순 tz 설정만 하고 현재 속한 tz 값 기준으로 질의를 작성 하게 되면
     KST 기준으로는 미래에 대한 datetime 값으로 질의를 하게 되어 데이터가 존재 하지 않을 수 있습니다.

  QueryDSL UTC 값 변환을 위한 TZ 설정과 값은 아래와 같이 해야 동작 합니다.
    KST 기준으로 오전 11시 보다 큰 값으로 질의 하고자 할 때 Elasticsearch 는 UTC 기준으로
    오전 2시 보다 큰 값으로 질의가 되어야 합니다.
      "time_zone": "+09:00",
      "gte": "2022-11-18T11:00:00.000"
      to
      "gte": "2022-11-18T02:00:00.000"
    와 같이 실제 Elasticsearch 에 저장 되는 UTC 값으로 변환 되어 질의하게 됩니다.
    아래와 같이 설정 되면 동작 하지 않습니다.
      "time_zone": "+09:00",
      "gte": "2022-11-18T11:00:00.000Z"
    Z 가 들어 가게 되면 TZ 설정이 적용 무시 되고 값 자체를 UTC 값으로 질의 하게 됩니다.

Z 는 java.time 아래 클래스 관련 설명이 되어 있습니다. (소스코드 참고하세요.)

:

[Elasticsearch] Document Count 정보가 필요해.

Elastic/Elasticsearch 2022. 11. 16. 11:25

용도와 목적에 맞게 선택해서 사용 하면 될 것 같습니다.

 

1. Date Histogram

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html

 

2. Count API

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/cat-count.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/search-count.html

 

3. Stats API

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/indices-stats.html

 

문서 수가 가끔 필요할 때가 있습니다.

제공 하는 API 를 활용해서 목적에 맞게 사용 하면 될 것 같습니다.

:

[Elasticsearch] Keword Field 내 Normalizer 선언 시 주의 사항.

Elastic/Elasticsearch 2022. 11. 14. 21:23

공홈 레퍼런스 문서)

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/term-level-queries.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/normalizer.html

 

한 줄 요약)

Keyword field 의 경우 normalizer 선언을 할 경우 index analyzer 뿐만 아니라 search analyzer 에도 동일하게 적용 됩니다.

 

보통 Keyword field 사용 시 term level query 를 사용하게 되면 검색어에 대한 형태소 분석 없이 token 에 대한 exact matching 을 한다고 가정 하게 됩니다.

이 경우에 해당 하기 위해서는 keyword field 선언 시 normalizer 선언이 없어야 적용이 됩니다.

 

아래는 관련 코드에 대해서 일부 snippet 한 내용입니다.

NamedAnalyzer normalizer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer searchAnalyzer = Lucene.KEYWORD_ANALYZER;
NamedAnalyzer quoteAnalyzer = Lucene.KEYWORD_ANALYZER;
String normalizerName = this.normalizer.getValue();

KeywordFieldMapper 클래스에 선언된 코드 입니다.

보시면 기본 Search Analyzer 는 Keyword Analyzer 입니다.

...중략...
searchAnalyzer = quoteAnalyzer = normalizer;
...중략...

코드 중간에 들어가 보면 이와 같이 선언 된 것을 보실 수 있습니다.

 

그리고 노말라이저 선언이 없으면 

searchAnalyzer = Lucene.WHITESPACE_ANALYZER;

Whitespace Analyzer 로 선언 되는 것도 확인이 가능 합니다.


보시면 아시겠지만 기본적으로 Keyword type 에 선언 되는 Search Analyzer 는 Lucene.KEYWORD_ANALYZER 로 선언 되게 되어 있습니다.
즉, Normalizer 선언이 없으면 기본이 키워드 인거죠. 그래서 별도 형태소 분석 과정이 없다보 인식 하는 건데 사실 없다고 보기 어렵고 Keyword Analyzer 의 Token Filter 를 따른다고 이해 하는게 맞습니다.


https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-analyzer.html
이 분석기는 아무런 선언을 하지 않으면 noop 에  정확히 텍스트가 일치해야 하는 분석기 입니다.
근데 색인 시점에 whitespace 를 포함한 텍스트를 keyword 로 선언 하고 이걸 whitespace 로 토큰 분해 하고 싶을 경우 "split_queries_on_whitespace" 이 옵션을 true 로 해주시면 됩니다.


그럼 KeywordAnalyzer/Tokenizer 이넘의 기본 형태소 분석은 그냥 텍스트를 하나의 토큰으로 분석 한다고 이해 하시면 되겠습니다.
여기서 whitespace 단위로 분해하고 싶으면 바로 위에 옵션 활용, 그리고 normalizer 는 토큰에 적용 되는데 search analyzer 에 반영 된다는 걸 기억 하면 됩니다.
문서에 나와 있던 내용 그대로 이고요. 코드 상으로는 어떻게 되어 있을까 궁금해서 찾아본 내용 공유 드립니다. ^^

보셔야 하는 클래스는

  • KeyowrdFieldMapper
  • KeywordAnalyzer
  • KeywordTokenizer

 

 

 

 

 

 

:

[Elasticsearch] Elasticsearch ES-Hadoop 내 Spark Bulk Request Error Handler

Elastic/Elasticsearch 2022. 9. 20. 12:35

Spark 을 이용해서 Elasticsearch 로 Bulk Request 를 사용할 경우 내부에서는 BulkProcessor 를 이용해서 요청을 하게 됩니다.
보통 BulkRequest 사용 시 색인 요청한 문서중 일부 오류가 발생 하는 경우 전체 문서 색인이 실패 하는 것이 아닌 오류 문서만 색인이 안되고, 나머지 문서들은 색인이 완료 되는데요. 
ES-Hadoop 내 Spark 의 경우 기본 Error Handler 가 AbortOnFailure 라서 요청한 모든 문서가 색인이 실패 하게 됩니다.
이를 변경 하기 위해서는 Error Handler 설정을 아래와 같이 변경하고 사용 하시면 됩니다.

[참고문서]
https://www.elastic.co/guide/en/elasticsearch/hadoop/8.4/errorhandlers.html#errorhandlers-bulk-use

[설정]

example)
es.write.data.error.handlers = log

SparkSession.builder().appName("...").config("es.write.rest.error.handlers", "log");


[참고코드]

// BulkWriteHandlerLoader / BulkWriteErrorHandler

@Override
protected IBulkWriteErrorHandler loadBuiltInHandler(AbstractHandlerLoader.NamedHandlers handlerName) {
    ErrorHandler<BulkWriteFailure, byte[], DelayableErrorCollector<byte[]>> genericHandler;
    switch (handlerName) {
        case FAIL:
            genericHandler = AbortOnFailure.create();
            break;
        case LOG:
            genericHandler = DropAndLog.create(new BulkLogRenderer());
            break;
        case ES:
            genericHandler = ElasticsearchHandler.create(getSettings(), new BulkErrorEventConverter());
            break;
        default:
            throw new EsHadoopIllegalArgumentException(
                    "Could not find default implementation for built in handler type [" + handlerName + "]"
            );
    }
    return new DelegatingErrorHandler(genericHandler);
}

기본적으로는 BulkRequest 와 BulkProcessor 에 대해서 문서를 찾아 보시면 도움이 되실 것 같습니다.

 

Thanks, 캉테

:

[Elasticsearch] Arirang Plugin on Elasticsearch 8.3.2

Elastic/Elasticsearch 2022. 7. 20. 13:47

Elasticsearch 8.3.2 + Lucene 9.2.0 에서 변경된 내용을 정리해 봅니다.

 

Lucene 8.11 to 9.2)

pom.xml 내 수정

# lucene-analyzers-common 은 9.x 에서는 더 이상 지원 하지 않음
<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-analyzers-common</artifactId>
  <version>${lucene.version}</version>
</dependency>
to
<dependency>
  <groupId>org.apache.lucene</groupId>
  <artifactId>lucene-analysis-common</artifactId>
  <version>${lucene.version}</version>
</dependency>

package 변경

org.apache.lucene.analysis.util.TokenFilterFactory
to
org.apache.lucene.analysis.TokenFilterFactory

org.apache.lucene.analysis.standard.ClassicFilter
to
org.apache.lucene.analysis.classic.ClassicFilter

org.apache.lucene.analysis.util.TokenizerFactory
to
org.apache.lucene.analysis.TokenizerFactory

org.apache.lucene.analysis.util.TokenFilterFactory
to
org.apache.lucene.analysis.TokenFilterFactory

org.apache.lucene.analysis.util.TokenFilterFactory
to
org.apache.lucene.analysis.TokenFilterFactory

 

elasticsearch analyzer plugin)

# AbstractIndexAnalyzerProvider 에서 IndexSettings 제거됨

org.elasticsearch.client.node.NodeClient
to
org.elasticsearch.client.internal.node.NodeClient

JDK 수정

build 시 jdk 17 사용
$jenv local 17

<java.version>17</java.version> 수정

❖ lucene 에서는 analyzer 패키지 변경이 있었으며, elasticsearch 에서는 NodeClient 에 대한 패키지 변경이 있었습니다.

:

[Elasticsearch] Filter Aggregation 사용하기.

Elastic/Elasticsearch 2022. 7. 18. 18:50

보통 Query 절에서 문서를 필터링 하고 Aggs 에서 집합/분석 질의를 하게 됩니다.

이 경우 성능적 잇점을 가져 가기 위해서는 보통 아래 두 가지 설정만 잘 사용 하면 됩니다.

 

1. Query 절은 Non-Scoring 질의를 사용하고

2. Size 파라미터 값을 0 으로 사용하고

 

그 이외는 기본적으로 Elasticsearch 에서  Cache 기능이 잘 동작 하기 때문에 크게 고민을 하지 않으셔도 어느 정도의 성능은 나온다고 보시면 됩니다.

 

Bucket Aggregation 중 Query 절에서 Filtering 하는 것과 같은 기능이 있어서 문서 링크와 주의 사항(?) 올려 봅니다.

 

아래 두 질의는 같은 결과를 리턴 합니다.

 

Case 1)

POST /sales/_search?size=0&filter_path=aggregations
{
  "query": { "term": { "type": "t-shirt" } },
  "aggs": {
    "avg_price": { "avg": { "field": "price" } }
  }
}

 

Case 2)

POST /sales/_search?size=0&filter_path=aggregations
{
  "aggs": {
    "t_shirts": {
      "filter": { "term": { "type": "t-shirt" } },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } }
      }
    }
  }
}

여기서 C1, C2 중 어떤게 좀 더 성능적으로 우세 할까요?

공홈 문서에 따르면 Sub Aggregation. 을 가지는 Filter Aggregation 보다는 Top Level Query 를 사용하는게 더 빠르다고 합니다.

그리고 다수의 Filter Aggregation 을 사용 하는 것 보다는 Filters Aggregation 을 사용 하는게 더 빠르다고 하니 참고 해서 사용 하시기 바랍니다.

 

제가 사용 한다고 하면 Top Level Query 에 Filter Query 나 Non-Scoring Query 를 이용해서 사용 할 것 같습니다.

 

 

 

:

[Elasticsearch] Common Options 활용

Elastic/Elasticsearch 2022. 7. 18. 12:37

공식 문서)

https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html

 

Response Filtering)

https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#common-options-response-filtering

 

_search REST API 사용 시 유용하게 활용이 가능 합니다.

잘 응용해서 사용하세요.

 

결과 내 JSON Result 에서 filter_path 를 통해서 필요한 결과를 parsing 할 수 있습니다.

:

[Elasticsearch] Text Analysis, Performance Aggs.

Elastic/Elasticsearch 2022. 7. 14. 19:32

Aggregation 기능을 이용해서 Text 분석을 하고 싶을 때가 있습니다.

X-pack basic 범위에서 가능 하면 더 좋겠죠.

 

아래 공홈 문서 보시고 참고해 보시면 좋을 것 같습니다.

 

 - Text Analysis
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-categorize-text-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-multi-terms-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-rare-terms-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significanttext-aggregation.html

- Aggs Performance
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html

:

[Elasticsearch] Index Template 사용 시 Mapping 정보 오류

Elastic/Elasticsearch 2022. 7. 14. 19:30

사용하다 보면 정말 별거 아닌 건데 눈에 잘 안보일 때가 있습니다.

 

에러 메시지)

"reason"=>"failed to parse field [message] of type [text] in document with id '3UI29IEBerapX-zaQi4L'. 
Preview of field's value: 
...중략...
"caused_by"=>{"type"=>"illegal_state_exception", "reason"=>"Can't get text on a 
START_OBJECT at 1:529"}

 

이런 에러메시지를 접하게 되면 두 눈 크게 뜨고 Template 에서 정의한 type 정보와 실제 들어 오는 값이 잘 매핑이 되어 있는지 확인을 해보시기 바랍니다.

 

모니터는 큰걸로 글자 크기는 크게 해서 보세요. 

: