query
q 매개변수에 필드 지시자가 없을 경우 df 매개변수로 기본 검색 필드를 지정가능
analyzer 프로퍼티는 질의 분석에 사용될 분석기 이름 정의
default_operator 프로퍼티는 질의에 사용될 기본 부울 연산자를 지정 explain 매개변수를 true로 지정하면 결과의 다큐먼트마다 질의 해설 정보를 추가
다큐먼트 마다 색인이름, 타입이름, 다큐먼트 식별자, _source필드 반환

 

  • 독자적인 정렬 방식을 사용하여 다큐먼트에 대한 점수를 추적할때 track_scores=true 옵션 추가
  • 검색 타임아웃 지정 timeout=5s
  • 결과 윈도우 크기 지정 size=10&from=2 (2번째 결과부터 5개 반환)
  • 검색 타입 search_type 매개변수를 이용해 지정가능 (dfs_query_then_fetch, dfs_query_and_fetch, query_then_fetch, query_and_fetch, count, scan)
  • 확장된 키워드 소문자로 만들기 lowercase_expanded_term=true
  • 와일드카드와 접두어 분석 사용 analyze_wildcard=true
  • 연산자와 증가값을 이용한 중요도 설정 title:book^4
  • numeric_detection:true 문자열을 숫자로 인지하여 검색 가능
  • dynamic_date_formats 새 문자열 필드를 검사하여 내용이 에 지정된 날짜 패턴과 일치하는지 확인합니다
  • dynamic:false 자동 필드 추가 기능 off
  • 타입 속성 문자열, 숫자, 날짜, 부울, 바이너리 설정 가능 index_name: 색인에 저장될 필드 이름, 정의하지 않으면 해당 필드를 정의한 객체 이름으로 설정된다
  • index: analyzed와 no 값으로 설정 가능, 문자열 필드일 경우 not_analyzed라고 설정 가능, analyzed 필드는 색인되므로 검색 가능한 필드, no로 설정하면 검색 불가능한 필드, not_analyed인 경우 필드는 색인되지만 분석되지는 않아 검색어가 완벽하게 일치해야 결과에 포함된다. index 프로퍼티를 no로 설정하면 해당 필드의 include_in_all 프로퍼티를 비활성화 한다
  • store: yes로 설정하면 필드의 원본 값을 색인에 기록, no는 기본값으로 원본 내용을 결과에 담아 반환하지 않는다. 색인은 되어 있으므로 이 필드를 대상으로 자료를 검색가능하다
  • boost: 기본값은 1, 속성값이 높을수록 해당 필드의 값이 중요하다
  • null_value: 필드가 색인된 다큐먼트의 일부로 포함되지않은 경우 색인에 기록될 값을 명세, 필드 생략이 기본 방식
  • copy_to: 모든 필드값을 복사할 필드를 명세
  • include_in_all: 대항 필드가 _all 필드에 반드시 포함되어야 하는지 명세
  • 문자열 속성 term_vector: no(기본값), yes, with_offsets, with_positions, with_positions_offsets 라는 값 설정 가능, 루씬 키워드 백터 계산 방식 정의
  • omit_norms: 분석될 문자열 필드 false(기본값), 색인되지만 분석되지 않을 문자열 true
  • analyzer: 색인과 검색을 위해 사용될 분석기 이름 정의, 전역으로 정의된 분석기 이름 사용
  • index_analyzer: 색인을 위해 사용할 분석기 이름
  • search_analyzer: 특정 필드로 전송한 질의문자열의 일부를 처리하기 위해 사용할 분석기 이름 정의
  • norms.enabled: 특정 필드를 위해 norms를 메모리에 올릴지 여부, 기본 true=메모리에 올린다
  • norms.loading: eager는 해당 필드에 대한 norms가 항상 메모리에 올려져 있음, lazy는 필요할 때만 메모리에 올림
  • position_offset_gap: 기본값 0, 색인에서 이름이 동일한 필드의 인스턴스 사이에 떨어진 차이 명세
  • index_options: 키워드를 담은 구조체인 출현 목록을 위한 색인 옵션 정의, docs: 다큐먼트번호만 색인, freqs: 다큐먼트 번호와 키워드빈도 색인, positions: 다큐먼트 번호와 키워드빈도와 위치 색인(기본값)
  • ignore_above: 필드의 최대 크기를 글자 수로 정의, 크기가 더 큰 값이 들어올 경우 무시된다.
  • 숫자 속성 byte, short, integer, long, float, double precision_step: 필드값에 대해 생성될 키워드 수 명세, 값이 작을 수록 생성되는 키워드 수가 늘어난다, 값 당 키워드 수가 많을수록 색인 비용이 크지만 범위 질의는 빨라진다. 기본값은 4
  • ignore_malformed: 기본값 false, 형식이 엉망이인 값을 제외하려면 true로 설정
  • 날짜 속성 기본적으로 UTC로 저장 format: 날짜 형식 명세, 기본값은 dateOptionalTime
  • precision_step: 필드값에 대해 생성될 키워드 수 명세, 값이 작을 수록 생성되는 키워드 수가 늘어난다, 값 당 키워드 수가 많을수록 색인 비용이 크지만 범위 질의는 빨라진다. 기본값은 4
  • token_count: 타입 필드에 제공된 텍스트를 저장하고 색인하는 대신 필드에 얼마나 많은 단어가 존재하는지에 대한 색인 정보를 저장하게 만든다.
  • 분석기 standard: 유럽 언어에 맞춘 표준 분석기 simple: 문자를 기준으로 제공된 값을 분리, 소문자로 변환 whitespace: 여백 문자를 기준으로 제공된 값을 분리 stop: 제공된 불용어 집합에 기반해 자료를 필터링 keyword: 제공된 값을 그대로 전달하는 분석기, not_analyzed로 특정 필드를 명세하는 경우와 동일한 효과 pattern: 정규 표현식을 사용해 유연하게 텍스트를 분리 lanuage: 특정 언어를 위해 동작하게 설계된 분석기 snowball: standard와 유사하지만 어간 추출 알고리즘을 추가로 제공
  • "similarity": "BM25" 점수 지수를 계산하기위해 BM25를 사용하여 필드 정의
  • explain API 점수 설명하기, "explain=true" 설정 혹은 url에 "_explain "  지정
  • 질의를 실행하는 과정에서 각 샤드별로 얼마나 많은 시간이 소요되는지 확인 -> "profile": true 사용
  • 필드 일치 요구 require_field_match: true로 설정, 질의와 일치하는 필드만 보여주기를 원하는 경우

 

 

term 질의
대상 필드에 키워드가 존재하는 다큐먼트와 일치하는지만 판단, 정확하지만 분석되지 않은 키워드
색인된 다큐먼트에 포함된 키워드와 정확히 일치, boost 속성 포함 가능

terms 질의
내용에 특정 키워드가 여러 개 들어 있는 다큐먼트와 일치하는지 판단
분석되지 않은 여러 키워드와 일치하는 결과 제공
minimum_match 프로퍼티로 일치하는 개수 설정 가능

match_all 질의
색인에 존재하는 모든 다큐먼트와 일치하는 결과 제공, boost 속성 포함 가능

common 키워드 질의
불용어를 사용하지 않을 때 흔히 사용하는 단어에 대한 질의 관련성와 정확성 개선을 위해 사용
질의를 두 그룹으로 나눠 첫번째 그룹은 중요한 키워드로 구성, 수행 후 두번 째 그룹에 대해 질의 수행

- query: 실재 질의내용 정의
- cutoff_frequency: 높은 빈도 그룹과 낮은 빈도 그룹의 기준인 퍼센트 값 지정
- low_freq_operator: or나 and로 설정 가능, 낮은 빈도 키워드 그룹에서 질의 구성하기 위해 부울 연산자 명세, 모든 키워드가 존재하기를 원한다면 and로 설정
- high_freq_operator: or나 and로 설정 가능, 높은 빈도 키워드 그룹에서 질의 구성하기 위해 부울 연산자 명세, 모든 키워드가 존재하기를 원한다면 and로 설정
- minimum_should_match: 일치하기 위해 다큐먼트에 존재해야 할 최소 키워드 수 명세
- boost: 다큐먼트 점수에 반영할 중요도 정의
- analyzer: 질의 텍스트를 분석하기 위해 사용할 분석기 이름과 기본 분석기 정의
- disable_coord: 기본값 false, 다큐먼트가 포함하는 모든 질의 키워드의 비율에 기반한 점수 지수 계산 활성화 여부

match 질의
질의 매개변수로 넘긴 값을 받아 분석한 다음 적절한 질의 생성
루씬 질의 구문을 지원하지않는다

부울 match 질의
제공된 텍스트를 분석하고 bool 질의를 생성
- operator: or, and로 설정, 기본값 or
- analyzer: 질의 텍스트를 분석하기 위해 사용할 분석기명 지정
- fuzziness: 퍼지fuzzy 질의 생성
- prefix_length: 퍼지 질의 동작 방식 제어
- max_expansions: 퍼지 질의 동작 방식 제어 zero_terms_query: 분석기가 모든 키워드를 제거할 때 질의 동작 방식 명세, none 기본값
- cutoff_frequency: 질의를 높은 빈도 키워드와 낮은 빈도 키워드라는 두 그룹으로 나눈다

{
    "query": {
        "match": {
            "title" : {
                "query": "crime and punishment",
                "operator": "and"
            }
        }
    }
}



match_phrase 질의
분석된 텍스트에서 구phrase 질의를 생성
- slop: 구를 판별하기 위해 키워드 사이에 알려져 있지 않은 단어가 얼마나 많이 들어갈 수 있는지를 정의하는 정수값
- analyzer: 질의 텍스트를 분석하기 위해 사용할 분석기 이름과 기본 분석기를 정의

{
    "query": {
        "match_phrase": {
            "title" : {
                "query": "crime and punishment",
                "slop": 1
            }
        }
    }
}



multi_match 질의
fields 매개변수에 담긴 여러 필드를 대상으로 수행
- use_dis_max: 부울값 정의, 기본값 true, dismax 질의나 bool 질의를 설정
- tie_breaker: use_dis_max 매개변수를 true로 설정한 경우에만 사용, 최저 점수 질의 항목과 최대 점수 질의 항목 사이의 균형을 명세

{
    "query": {
        "multi_match": {
            "query": "crime and punishment",
            "fields": ["title", "content"]
        }
    }
}



query_string 질의
아파치 루씬 질의 구문 지원

{
    "query": {
        "query_string": {
            "query": "title:crime^10 +title:punishment -otitle:cat +author:(+Fyodor +dostoevsky)",
            "default_field": "title"
        }
    }
}

# 중요도를 질의에 추가
# 가장 중요한 필드 to, 덜 중요한 필드 from
{
    "query': {
        "query_string": {
            "fields": ["from^5", "to^10", "subject],
            "query": "john",
            "use_dis_max": false
        }
    }
}

query: 질의 텍스트 명세
- default_field: 질의 실행을 위한 기본 필드 명세
- default_operator: 기본값 or, 기본 논리 연산자 명세
- analyzer: 질의를 분석하기 위해 사용할 분석기의 이름 명세
- allow_leading_wildcard: 와일드카드 문자를 키워드의 첫 글자로 허용할지 말지 명세, 기본값 true
- lowercase_expand_terms: 질의 재작성 결과로 만들어져야 하는 키워드가 소문자인지 여부 명세, 기본값 true
- enable_position_increments: 결과 질의에서 위치 증가 기능을 켤지 여부 명세, 기본값 true
- fuzzy_max_expansions: fuzzy 질의를 확장하는 최대 키워드 수 명세, 기본값 50
- fuzzy_prefix_length: 생성된 fuzzy 질의 접두어 길이를 명세, 기본값 0
- fuzzy_min_sim: fuzzy 질의에 대한 최소 유사성 명세, 기본값 0.5
- phrase_slop: 구에 대한 slop값 명세, 기본값 0
- boost: 중요도 값, 기본값 1.0
- analyze_wildcard: wildcard 질의가 생성한 키워드를 분석할지 여부, 기본값 false
- auto_generate_phrase_queries: 질의에서 자동으로 구 질의를 생성할지 여부, 기본값 false
- minimum_should_match: 다큐먼트와 일치한다고 가정하기 위해 충족해야 하는 절의 최소 부울 조건, 퍼센트가 정수값 사용
- lenient: 형식이 잘못된 오류 무시여부


simple_query_string 질의
오류가 발생해도 예외를 던지지 않는다

{
    "query": {
        "simple_query_string": {
            "query": "title:crime^10 +title:punishment -otitle:cat +author:(+Fyodor +dostoevsky)",
            "default_operator": "and"
        }
    }
}



ids 질의
식별자를 기준으로 반환된 다큐먼트를 필터링
"type": "book" 과 같이 특정 타입에 대해서만 검색 가능

{
    "query": {
        "ids": {
            "type": "book",
            "values": ["10", "15", "20"]
        }
    }
}



prefix 질의
해당 접두어로 시작하는 값이 특정 필드에 포함한 다큐먼트와 일치하는지 판단
boost 속성 포함 가능

{
    "query": {
        "prefix": {
            "title": "cri"
        }
    }
}



fuzzy_like_this 질의
more_like_this 질의와 유사, 퍼지 문자열을 사용, 키워드를 생성한 다음 최고로 차별화된 키워드를 고른다
- fields: 질의를 수행할 대상 필드
- like_text: 타큐먼트와 비교할 텍스트
- ignore_tf: 유사성 계산에서 키워드 빈도를 무시할지 여부, 기본값 false
- max_query_terms: 생성된 질의에 포함될 최대 질의 키워드 수 명세, 기본값 25
- min_similarity: 차별화된 키워드의 최소 유사성 명세, 기본값 0.5
- prefix_length: 차별화된 키워드의 공통 접두어 길이 명세, 기본값 0
- boost: 질의 중요도, 기본값 1.0
- analyzer: 제공된 질의를 분석하기 위해 사용할 분석기 이름

{
    "query": {
        "fuzzy_like_this": {
            "fields": ["title", "content"],
            "like_text": "crime punishment"
        }
    }
}



fuzzy_like_this_field 질의
fuzzy_like_this와 비슷, 단일 필드를 대상으로 동작

{
    "query": {
        "fuzzy_like_this_field": {
            "title": {
                "like_text": "crime punishment"
            }
        }
    }
}



fuzzy 질의
에디트 거리edit distance 알고리즘 기반, 검색된 다큐먼트를 대상으로 질의에 넘긴 키워드를 기준으로 삼아 에디트 거리를 계산
철자 오류에도 불구하고 관심이 있는 다큐먼트를 찾는데 성공
- value: 실제 질의
- boost: 중요도 값, 기본값 1.0
- min_similarity: 일치한다고 판단하기위한 키워드의 최소 유사성
- prefix_length: 공통 접두어 길이, 기본값 0
- max_expansions: 질의에서 확장될 최대 키워드 수 명세, 기본값 unbounded

 


wildcard 질의
*나 ? 같은 와일드 카드 사용 허용
boost 속성 포함

 


more_like_this 질의
제공된 텍스트와 유사한 다큐먼트 조회
- fields: 질의 대상 필드
- like_text: 다큐먼트와 비교할 텍스트
- percent_terms_to_match: 질의에 속한 키워드의 퍼센트, 기본값 0.3
- min_term_freq: 이 값보다 작을 경우 키워드를 무시할 기준이 되는 빈도, 기본값 2
- max_query_terms: 최대 질의 키워드 수 명세, 기본값 25
- stop_words: 무시할 단어의 배열
- min_doc_freq: 최소한 다큐먼트에 존재해야할 키워드 수, 기본값 5
- max_doc_freq: 최대한 다큐먼트에 존재 가능한 키워드 수, 기본값 unbounded
- min_word_len: 무시하지 않기 위한 단일 단어의 최소 길이, 기본값 0
- max_word_len: 무시하지 않기 위한 단일 단어의 최대 길이, 기본값 unbounted
- boost_terms: 개별 항목의 중요도 값, 기본값 1
- boost: 중요도 값, 기본값 1.0
- analyzer: 질의 분석기 이름

 


more_like_this_field 질의
more_like_this 질의와 유사, 단일 필드에 대해서만 동작

{
    "query": {
        "more_like_this_field" : {
            "title": {
                "like_text": "crime and punishement",
                "min_term_freq": 1,
                "min_doc_"freq": 1
            }
        }
    }
}



range 질의
특정 범위에 속한 필드값을 포함한 다큐먼트를 찾는다
단일 필드에서만 사용 가능
- gte: 지정한 값보다 크거나 같은 값인지 판단
- gt: 지정한 값보다 큰 값인지 판단
- lte: 지정한 값보다 작거나 같은 값인지 판단
- lt: 지정한 값보다 작은 값인지 판단
{
    "query": {
        "range" : {
            "year": {
                "gte": 1700,
                "lte": 1900
            }
        }
    }
}

 


dismax 질의
모든 하위 질의가 반환한 다큐먼트를 결합해결과를 이를 반환할 경우 유용
점수가 낮은 하위 질의가 다큐먼트의 최종 점수에 영향을 미치는 방법을 통제할 수 있다

# dismax 질의를 사용하려면 질의 내용에 use_dis_max 프로퍼티를 true로 설정해야 함
{
    "query": {
        "query_string": {
            "query": "crime punishment",
            "fields": ["title", "content"],
            "use_dis_max": true
        }
    }
}

DisMax는 Disjunction Max 의 줄임말
분리 Disjunction는 여러 필드에 대해 검색이 실행되며 필드마다 중요도 가중치를 다르게 줄 수 있다
최대는 해당 키워드에 대한 최고 점수만 마지막 다큐먼트 점수에 포함되며 일치하는 키워드를 담은 모든 필드의 점수를 합치지 않는다


regexp 질의
정규표현식을 사용

 


bool 질의
- should: 조건에 따라 일치할 수도 일치하지 않을 수도 있다
- must: 반드시 일치해야 한다
- must_not: 반드시 일치하지 않아야 한다
- boost: 중요도 값, 기본값 1.0
- minimum_should_match: 충족해야 하는 should 절의 최소 부울 조건 제어, 퍼센트나 정수값 사용
- disable_coord: 기본값 false, 점수 지수 계산을 활성화/비활성화, 정확도는 떨어지나 조금 빠른 질의를 위해서는 true로 설정

 


boosting 질의
질의 중 하나가 반환하는 다큐먼트 점수를 낮춘다
positive 절은 다큐먼트 점수가 변경되지 않고 남을 질의
negative 절은 다큐먼트 점수를 낮춰야 할 질의
negative_boost 절은 negative 절의 질의 점수를 낮추기 위한 중요도 값

# 일치하는 모든 다큐먼트의 점수를 줄이고 싶을 때 질의의 일부로 사용
{
    "query": {
        "boosting': {
            "positive": {
                "term": {
                    "available": true
                }
            },
            "negative": {
                "match": {
                    "author": "remarque"
                }
            },
            "negative_boost": 0.1
        }
    }
}



constant_score 질의
다른 질의를 감싸며 감싼 질의가 반환하는 다큐먼트마다 상수 점수를 반환
필터나 질의를 받아 점수로 사용하는 값을 명시적으로 설정, boost 매개변수를 이용해 일치하는 다큐먼트마다 점수 부여

{
    "query": {
        "constant_score': {
            "query": {
                "query_string": {
                    "query": "available:false author:heller"
                }
            }
        }
    }
}



indices 질의
여러 색인에 다른 질의를 수행할 때 사용
색인 배열과 질의 두가지 값 필요


function_score 질의
점수 계산에 비용이 들어갈 경우 유용, 필터링된 다큐먼트의 점수를 계산

임의의 함수에 숫자로 점수를 지정하여 초기 질의에 맞는 문서의 점수를 결정하는데 세부적으로 조절할 수 있다

{
    "query": {
        "function_scroe": {
            "query": { ... },
            "filter": { ... },
            "functions": [
                {
                    "filter": { ... },
                    "FUNCTION": { ... }
                }
            ],
            "boost_mode": "...",
            "score_mode": "...",
            "max_boost": "...",
            "boost": ..."
        }
    }
}

- boost_mode: 질의 점수와 결합될 함수 질의 점수 계산 방법 정의
- multiply: 기본 동작 방식, 함수에서 계산된 점수를 질의 점수에 곱한다
- replace: 질의 점수를 완전히 무시하고 함수가 계산한 점수 반환
- sum: 질의 점수와 함수 점수를 합한다
- avg: 질의 점수와 함수 점수의 평균값
- max: 함수 점수와 질의 점수 중 최대값
- min: 함수 점수와 질의 점수 중 최소값
- score_mode: 함수가 계산한 모든 점수를 결합하는 방법 정의- 
- multiply: 기본 동작 방식, 점수의 곱 반환
- sum: 점수의 합
- avg: 점수의 평균
- first: 다큐먼트와 일치하는 필터가 존재하는 첫 함수의 점수 반환
- max: 최대 점수
- min: 최소 점수
- functions 절에 포함할 수 있는 함수- 
- boost_factor: 다큐먼트의 점수에 주어진 값을 곱한다
- script_score: 반환하는 점수를 계산하기 위해 스크립트를 사용
- random_score: 초기 seed 값을 명세해 가상 난수 점수롤 생성
- decay: 거리가 멀어짐에 따라 decay 함수가 계산한 점수도 낮아진다, 특정 지점에서 거리를 기준으로 중요도를 높이는 경우 사용

 


향후 지원이 중단될 질의
custom_boost_factor, custom_score, custom_filters_score

 


질의 재작성
prefix, wildcard 질의와 같은 복수 키워드 질의는 성능적인 이유로 인해 재작성 기능 사용
질의 재작성 방식을 제어하기 위해 복수 키워드 질의에서 rewriter 매개변수 사용 가능

{
    "query": {
        "prefix": {
            "title": "s",
            "rewrite": "constant_score_boolean"
        }
    }
}

- scoring_boolean: 생성된 각각의 키워드를 부울 should 절로 변환
- constant_score_boolean: scoring_boolean와 비슷 점수 계산이 없어 CPU 덜 소비
- constant_score_filter: 키워드에 대한 모든 다큐먼트를 표시하게 동작하는 전용 필터 생성
- top_terms_N: 생성된 각각의 키워드를 부울 should 절로 변환, 부울 절의 최대 제약을 넘기지 않게 상위 점수 N개만 유지
- top_terms_boost_N: top_terms_N과 유사, 점수는 질의가 아닌 중요도로 계산

 

 

search_type
내부적으로 질의를 처리하는 방식 선택
색인의 크기가 커져도 괜찮다면 퍼지/와일드카드/구문 쿼리 대신 엔그램과 싱글을 사용하면 검색이 빨라짐
스크립트 사용 보다 색인 시 새로운 필드를 추가하여 검색 속도 향상
스크립트가 자주 변경되지 않으면 elasticsearch 플러그인 형태로 네이티브 스크립트 작성
샤드별로 문서 빈도가 불균형하면 dfs_query_then_fetch 사용
많은 문서를 탐색해야 한다면 스캔 검색 사용
search_type 요청 매개변수를 추가하고 아래 값 중 하나를 선택
- query_then_fetch: 기본값, 다큐먼트를 정렬하고 순위를 매기고자 할때, 전체 샤드의 검색이 모두 수행된 후 결과 출력, 전체 취합된 결과를 size 매개변수에서 지정한 수만큼 출력
- query_and_fetch: 모든 샤드를 대상으로 병렬로 질의 수행, 샤드별로 검색되는대로 결과 출력, size * 샤드 갯수만큼 출력
- dfs_query_then_fetch: query_then_fetch와 같으나 정확한 스코어링을 위해 검색어들을 사전 처리, 분산된 키워드 빈도를 계산하는 작업 추가 단계 존재
- dfs_query_and_fetch: query_and_fetch와 같으나 정확한 스코어링을 위해 검색어들을 사전 처리, 분산된 키워드 빈도를 계산하는 작업 추가 단계 존재
- count: 질의와 일치하는 다큐먼트 수만 반환
- scan: 질의가 엄청난 결과를 반환하리라 기대할 경우에 사용



검색 수행 우선순위
질의를 수행할 샤드 제어, preference 요청 매개변수에 설정
_primary 주 샤드에서만 실행, 색인에서 최신 정보를 사용하길 원하지만 자료가 바로 복제되지 않을 경우 유용
_primary_first 주 샤드에서 실행
_local 요청을 전송받은 노드의 사용 가능한 샤드에서 실행
_only_node:node_id 노드 식별자로 지정한 노드에서 실행
_preter_node:node_id 노드 식별자로 지정한 노드에서 실행, 해당 노드가 사용 불가할 경우 다른 노드에서 실행
_shards:1,2 샤드 식별자로 지정한 샤드에서 검색 연산 수행

 

 

'ElasticSearch' 카테고리의 다른 글

ES Rolling Restart  (0) 2022.09.12
ES 플러그인  (0) 2022.08.30
ES 하이라이팅  (0) 2022.08.30
ES 클러스터  (0) 2022.08.30
ES 세팅  (0) 2022.08.30

+ Recent posts