[Search] ES Query: must / should / filter / must_not
ES query, bool query, must, should, filter, must_not, match, term, range, query DSL, ESQL
정의
ES 의 Query DSL = JSON 기반 표현력 풍부한 쿼리 언어. bool query + leaf query 의 조합.
bool query: 4가지 절
flowchart LR
Bool[bool query]
Bool --> Must["must<br/>(AND, score 계산)"]
Bool --> Should["should<br/>(OR, score 가산)"]
Bool --> Filter["filter<br/>(AND, score 없음)"]
Bool --> MustNot["must_not<br/>(NOT, score 없음)"]
| 절 | AND/OR | Score | Cache |
|---|---|---|---|
must | AND | 예 | 안됨 |
should | OR | 예 (가산) | 안됨 |
filter | AND | 없음 | 예 (빠름!) |
must_not | NOT | 없음 | 예 |
IMPORTANT
Score 가 필요 없으면 항상 filter. must + 동일 조건보다 압도적으로 빠름 (cache + scoring 생략).
종합 예시
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "mechanical keyboard" } }
],
"should": [
{ "match": { "tags": "rgb" } },
{ "match": { "tags": "wireless" } }
],
"filter": [
{ "term": { "category": "input-device" } },
{ "range": { "price": { "gte": 50, "lte": 200 } } },
{ "term": { "in_stock": true } }
],
"must_not": [
{ "term": { "brand": "Brand-X" } }
],
"minimum_should_match": 1
}
}
}
해석:
title에 “mechanical keyboard” 매칭 (필수, score 계산)tags에 “rgb” 또는 “wireless” 있으면 가산 (minimum_should_match: 1적용)- category, 가격 50-200, 재고 있음 (필터, 빠름)
- Brand-X 제외
leaf query 카테고리
flowchart TB
Q[Leaf Queries]
Q --> FullText[Full Text]
Q --> TermLevel[Term Level]
Q --> Range[Range]
Q --> Geo[Geo]
Q --> Vector[Vector / Semantic]
Q --> Compound[Compound]
FullText --> M1[match, match_phrase, multi_match, match_phrase_prefix, query_string, simple_query_string]
TermLevel --> T1[term, terms, exists, prefix, wildcard, regexp, fuzzy, ids]
Range --> R1[range]
Geo --> G1[geo_distance, geo_bounding_box, geo_polygon]
Vector --> V1[knn, sparse_vector, text_expansion]
Compound --> C1[bool, dis_max, constant_score, function_score]
match vs term
// match: 분석기 적용 → tokenized 비교
{ "match": { "title": "Mechanical Keyboard" } }
// → tokens: ["mechanical", "keyboard"]
// → 둘 중 하나라도 매칭 (operator=or 기본)
// term: 분석 없이 *exact* (keyword 필드용)
{ "term": { "status": "active" } }
CAUTION
text 필드에 term 쿼리 = 원본 토큰 못 찾음 (분석기가 lowercase 등 했기 때문). text 는 match, keyword 는 term.
match_phrase + slop
{ "match_phrase": { "title": { "query": "mechanical keyboard", "slop": 1 } } }
- 연속된 토큰 매칭.
slop: 얼마나 떨어져도 OK (단어 거리).
multi_match
{
"multi_match": {
"query": "rabbit hat",
"fields": ["title^3", "description", "tags"]
}
}
- 여러 필드 동시 검색.
field^N: 가중치.- type:
best_fields,most_fields,cross_fields,phrase.
function_score (커스텀 ranking)
{
"query": {
"function_score": {
"query": { "match": { "title": "keyboard" } },
"functions": [
{ "filter": { "term": { "premium": true } }, "weight": 2.0 },
{ "field_value_factor": { "field": "popularity", "modifier": "log1p" } },
{ "gauss": { "created_at": { "origin": "now", "scale": "30d", "decay": 0.5 } } }
],
"boost_mode": "multiply"
}
}
}
| function | 의미 |
|---|---|
weight | 상수 곱 |
field_value_factor | 필드값 기반 (popularity 등) |
gauss / linear / exp | 거리 기반 감쇠 (시간, 위치) |
script_score | Painless 스크립트 |
random_score | 무작위 (A/B) |
ESQL (2024 GA)
SQL 같은 파이프 표기:
FROM logs-*
| WHERE @timestamp > NOW() - 7 days AND status_code >= 500
| STATS error_count = COUNT(*) BY service.name, host.name
| SORT error_count DESC
| LIMIT 20
TIP
DSL 의 복잡함 회피. 2026 시점 대시보드 / ad-hoc 쿼리 에서 ESQL 이 표준. Kibana 의 default 쿼리도 ESQL 전환 중.
동작 흐름
일반 검색 직관. ES 도 같은 query → ranking → top-K 흐름.
흔한 함정
WARNING
text에term= 매칭 0.keywordfield 사용 또는match.should만 사용 =minimum_should_match누락 → 0개 일치 OK. 명시 권장.- score 불필요한데
must= cache 못 씀. filter 로. wildcard,regexp,prefix남용 = 느림. 분석기 변경 + edge_ngram 으로 대체.
관련 위키
- elasticsearch-mapping (text vs keyword)
- elasticsearch-relevance-scoring (BM25)
- elasticsearch-vector-search (kNN + bool 결합)
- elasticsearch-aggregations (query 결과의 집계)
이 글의 용어 (4개)
- [Search] ES Aggregations: metric, bucket, pipelinesearch
- 정의 Aggregations (aggs) = ES 의 집계 분석. SQL 의 GROUP BY + 함수 + window. 검색 결과 또는 전체 위에서. 3가지 카테고리 Metric…
- [Search] ES Mapping: field type, dynamic, multi-fieldsearch
- 정의 Mapping = ES 의 schema. 각 필드의 type + analyzer + indexing 옵션. 대부분 immutable (재인덱싱 필요). Field Type …
- [Search] ES Relevance Scoring: BM25, TF-IDF, function_scoresearch
- 정의 Relevance Score ( ) = 쿼리와 문서의 매칭 강도. ES 7+ 의 기본은 BM25 (TF-IDF 의 발전형). BM25 공식 | 부분 | 의미 | |---|-…
- [Search] ES Vector Search: kNN, ELSER, RAGsearch
- 정의 ES 의 벡터 검색 = 임베딩 기반 의미 검색. kNN (Approximate Nearest Neighbor) 으로 수억 벡터 안에서 가까운 K개 찾기. 2026 시점의 E…
이 개념을 다룬 위키 페이지 (7)
- wiki[Search] ElasticSearch: Lucene 위 분산 검색 엔진
- wiki[Search] ES Aggregations: metric, bucket, pipeline
- wiki[Search] ElasticSearch 기본 원리: Inverted Index, Segment, Lucene
- wiki[Search] ES Mapping: field type, dynamic, multi-field
- wiki[Search] ES Relevance Scoring: BM25, TF-IDF, function_score
- wiki[Search] ES Sort: relevance, field, script, geo
- wiki[Search] ES Vector Search: kNN, ELSER, RAG
💬 댓글