Query DSL 정리 (실무 중심)

🔍 1. term 쿼리

{ "term": { "status": "active" } }
  • 정확히 일치하는 값을 찾을 때 사용
  • 형태소 분석되지 않은 필드 (keyword, int, boolean)에 적합
  • text 필드에는 text.keyword로 사용해야 정확히 일치
  • 실무: 상태, ID, 카테고리 코드 등

🔍 2. terms 쿼리

{ "terms": { "status": ["active", "ready"] } }
  • 여러 값 중 하나라도 일치하면 검색
  • IN 조건처럼 사용
  • 65,536개 이상의 값은 사용 불가 (성능 저하)

🔍 3. match 쿼리

{ "match": { "title": "엘라스틱 서치 강의" } }
  • text 필드에 사용
  • 형태소 분석됨 (자연어 검색)
  • 완전 일치 아님 → 관련된 문서도 나올 수 있음

🔍 4. match_phrase 쿼리

{ "match_phrase": { "title": "엘라스틱 서치 강의" } }
  • 정확한 문장 일치 (순서 유지)
  • 중간 단어 빠지면 매칭되지 않음

🔍 5. bool 쿼리

{
  "bool": {
    "must": [ ... ],        // 모두 만족 (AND)
    "should": [ ... ],      // 하나 이상 만족하면 OK (OR 느낌)
    "must_not": [ ... ],    // 만족하면 제외
    "filter": [ ... ]       // 점수 영향 없음, 빠름
  }
}

✔️ 실전 사용 예

{
  "bool": {
    "must": [
      { "term": { "status": "active" } },
      { "match": { "title": "엘라스틱" } }
    ],
    "filter": [
      { "range": { "created_date": { "gte": "now-7d/d" } } }
    ],
    "must_not": [
      { "term": { "is_deleted": true } }
    ]
  }
}

🔍 6. range 쿼리

{ "range": { "price": { "gte": 1000, "lte": 5000 } } }
  • 숫자나 날짜 필드에 범위 조건 적용
  • 실무: 가격, 날짜 필터링

🔍 7. exists 쿼리

{ "exists": { "field": "thumbnail_url" } }
  • 필드가 존재하는지 확인

🔍 8. wildcard / regexp / prefix

{ "wildcard": { "title": "엘라*" } }
  • wildcard, regexp, prefix는 느릴 수 있음
  • analyzed 되지 않은 keyword 필드에 사용 추천

🔍 9. multi_match

{
  "multi_match": {
    "query": "검색어",
    "fields": ["title", "description"]
  }
}
  • 여러 필드에 match 쿼리 적용

🔍 10. script 쿼리

{
  "script_score": {
    "query": { "match_all": {} },
    "script": {
      "source": "doc['click_count'].value * 0.5 + doc['like_count'].value"
    }
  }
}
  • 스크립트 기반 동적 스코어
  • 캐시 안 되고 느릴 수 있음 → 최소 사용 권장

✅ 실무 패턴 정리

목적쿼리
필터링 + 검색bool + must + filter
정확 조건term, terms
자연어 검색match, multi_match
날짜 조건range (filter 사용 권장)
제외 조건must_not
가중치 적용should, script_score
추천 기능should + minimum_should_match

📌 추천 실전 예시

1. 필터 조건 + 본문 검색

{
  "bool": {
    "must": [
      { "match": { "content": "엘라스틱서치 설정법" } }
    ],
    "filter": [
      { "term": { "status": "published" } },
      { "range": { "created_date": { "gte": "now-1M/M" } } }
    ]
  }
}

2. 추천어 기반 검색

{
  "bool": {
    "must": [
      { "term": { "status": "active" } }
    ],
    "should": [
      { "match": { "title": "엘라스틱" } },
      { "match": { "tags": "검색엔진" } }
    ],
    "minimum_should_match": 1
  }
}

⚠️ 주의할 점

  • text 필드에는 term ❌ → .keyword 사용
  • match는 유사도 기반 → 정확 검색은 term
  • filter는 점수 계산 안 함 → 빠름
  • should만 있을 경우 minimum_should_match 설정 안 하면 모두 미일치해도 통과 가능
  • script는 느림
  • wildcard, regexp는 느림 → 되도록 ngram 대체 고려