Elasticsearch 검색 1편 - match, term, bool
[ELK Stack]Elasticsearch 검색 1편 - match, term, bool
1. 검색 쿼리의 구조와 흐름
쿼리 방식 구분
1. 쿼리 스트링 (Query String)
- REST API의 URL에 파라미터 형식으로 조건을 붙여 검색하는 방식
- 간단한 테스트나 검색에는 용이하지만 조건이 복잡해질수록 가독성 및 유지보수성이 떨어짐
GET kibana_sample_data_ecommerce/_search?q=customer_full_name:Mary
2. 쿼리 DSL (Query Domain Specific Language)
- JSON 포맷을 활용하여 REST 요청의 본문(body)에 검색 쿼리를 명시
- 구조화된 쿼리, 복합 논리 연산, 스코어 조절, 정렬 등 복잡한 조건을 표현할 수 있음
GET kibana_sample_data_ecommerce/_search
{
"query": {
"match": {
"customer_full_name": "Mary"
}
}
}
응답 필드 제한
"_source": ["customer_full_name"]
- 원하는 필드만 응답 결과로 받아올 수 있음 → 데이터 양 절감 및 클라이언트 처리 성능 향상
검색 쿼리의 종류 분류
1. 리프 쿼리 (Leaf Query)
- 특정 필드에서 조건을 설정하는 가장 기본적인 쿼리
- ex)
match,term,range,multi_match
2. 복합 쿼리 (Compound Query)
- 여러 쿼리를 논리적으로 조합하는 상위 쿼리 구조
- ex)
bool,function_score,constant_score,dis_max
2. 리프 쿼리 상세 정리
match 쿼리 (전문 검색)
{
"match": {
"customer_full_name": "mary bailey"
}
}
text타입의 필드에서만 사용 가능- 분석기(analyzer)를 거쳐 토큰화된 단어 단위로 검색됨 →
mary,bailey - 기본 연산자는 OR: 두 단어 중 하나만 포함돼도 매칭
operator: and
{
"match": {
"customer_full_name": {
"query": "mary bailey",
"operator": "and"
}
}
}
→ 두 용어 모두 포함되어야 결과 반환
match_phrase 쿼리 (구문 일치 검색)
{
"match_phrase": {
"customer_full_name": "mary bailey"
}
}
- match 쿼리처럼 분석은 하지만, 단어의 순서와 위치까지 일치해야 결과 반환
- “mary bailey”는 OK, “bailey mary”는 NO
- 구문 검색이므로 검색 리소스 많이 사용됨
multi_match 쿼리 (다중 필드 검색)
{
"multi_match": {
"query": "mary",
"fields": [
"customer_first_name",
"customer_last_name",
"customer_full_name"
]
}
}
- 여러 필드에 대해 동시에 match 검색을 실행
- 내부적으로 각 필드마다 match 쿼리를 수행하고 가장 높은 score를 대표 score로 반환
와일드카드 필드 선택
"fields": ["customer_*_name"]
boost 가중치 적용
"fields": ["customer_full_name^3", "customer_last_name", "customer_first_name"]
- 특정 필드에 가중치 부여 → 해당 필드에서 매칭될 경우 스코어 우선 적용
term 쿼리 (정확 일치 검색)
{
"term": {
"customer_full_name.keyword": "Mary Bailey"
}
}
- 분석기를 거치지 않고 입력 값 그대로 일치 여부 판단
- 반드시
keyword타입 필드에서 사용해야 하며,text필드는 부적절 - 대소문자 민감함 (Mary ≠ mary)
terms 쿼리 (복수 값
{
"terms": {
"day_of_week": ["Monday", "Sunday"]
}
}
- SQL의
IN (...)조건과 유사
range 쿼리 (숫자, 날짜, IP 범위 검색)
{
"range": {
"timestamp": {
"gte": "2020-12-15",
"lte": "2020-12-16"
}
}
}
gte,lte,gt,lt네 가지 연산 지원- 날짜/숫자/IP 타입에서만 사용 가능 (keyword/text 타입에서는 불가)
상대 시간 표현
"gte": "now-1M"
- 상대 시간 표현식: now-1d, now-2h, now-30m 등 (주의:
M은 월, 소문자는 시/분/초)
date_range + relation
- 필드를
date_range타입으로 매핑한 경우, range 내부에서 relation 속성 사용 가능
| relation | 설명 |
|---|---|
| intersects | 범위가 일부라도 겹치면 매칭 |
| contains | 문서 범위가 쿼리 범위를 모두 포함할 경우에만 매칭 |
| within | 문서 범위가 쿼리 범위 내에 완전히 속할 경우만 매칭 |
→ 실무에서 “사용자의 활동 기간이 이 특정 기간을 모두 포함해야 함” 같은 조건 설정 시 유용
3. 복합 쿼리 - bool 쿼리
bool 쿼리 구조
- 여러 리프 쿼리를 논리 조합하여 검색할 수 있는 가장 기본적인 복합 쿼리
구성 요소
| 요소 | 설명 | 연산 의미 | 스코어 영향 |
|---|---|---|---|
| must | 모두 만족해야 매칭 | AND | 있음 |
| must_not | 해당되면 제외 | NOT | 없음 |
| should | 하나라도 만족하면 포함 (or) | OR | 있음 |
| filter | 조건 필터링만, 스코어 영향 없음 | - | 없음 |
bool 했던거 모음
must + must_not 조합
{
"bool": {
"must": {
"match": {"customer_full_name": "mary"}
},
"must_not": {
"term": {"customer_last_name": "bailey"}
}
}
}
filter 단독 사용 (스코어 계산 없음)
{
"bool": {
"filter": {
"term": {"day_of_week": "Sunday"}
}
}
}
must + filter 조합 (성능 최적화)
{
"bool": {
"must": {
"match": {"customer_full_name": "mary"}
},
"filter": {
"range": {
"products.base_price": {
"gte": 30,
"lte": 60
}
}
}
}
}
should 여러 개 (OR 조건)
{
"bool": {
"should": [
{"term": {"day_of_week": "Sunday"}},
{"match": {"customer_full_name": "mary"}}
]
}
}
must + should (스코어 향상 용도)
{
"bool": {
"must": {"match": {"customer_full_name": "mary"}},
"should": {"term": {"day_of_week": "Sunday"}}
}
}
댓글남기기