Dsl
Dsl 카테고리의 모든 포스트 - 한국어
3개의 포스트
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
대체 고려
심화 쿼리 정리 (실무 중심)
1. 🔧 function_score 쿼리
📌 개념
검색 점수(score)에 함수를 적용해서 가중치(weighting)나 랜덤성 부여
✅ 사용 예시
{
"function_score": {
"query": { "match": { "title": "엘라스틱" } },
"functions": [
{
"filter": { "term": { "is_premium": true } },
"weight": 2
},
{
"random_score": {}
}
],
"boost_mode": "multiply"
}
}
💡 실무 활용
- 프리미엄 콘텐츠 우선 노출
- 추천 콘텐츠 랜덤성 부여
- 클릭 수, 조회 수 기반 가중치 조정
⚠️ 주의사항
- 함수마다 성능 차이 큼 (특히 script 포함 시)
boost_mode
,score_mode
조정 필요
2. 🧮 script_score 쿼리
📌 개념
커스텀 스크립트로 score 직접 계산
페이징 전략 정리 (실무 중심)
✅ 1. 기본 페이징: from + size
🔹 개념
SQL의 OFFSET, LIMIT처럼 특정 위치부터 몇 개를 가져옴.
{
"query": { "match_all": {} },
"from": 0,
"size": 10
}
✅ 특징
- 가장 기본적인 방법
- from=0, size=10 → 1페이지, from=10, size=10 → 2페이지
⚠️ 주의사항
- from이 클수록 성능이 나빠짐 (deep pagination)
- 기본 최대는 10,000 (index.max_result_window 초과 시 에러)
💡 실무 팁
- 리스트 조회에는 적합
- 대용량 페이징에는 search_after 또는 scroll 사용
✅ 2. 안정적인 순차 페이징: search_after
🔹 개념
정렬된 필드 기준으로 커서를 넘겨 다음 페이지 요청