Percolate 쿼리
Percolate 쿼리
percolate 쿼리는 주어진 문서와 일치하는 저장된 쿼리를 찾아요. 일반 검색과 반대로 쿼리에 맞는 문서를 찾는 대신 문서에 맞는 쿼리를 찾는 작업이에요. 알림, 통지, 역방향 검색(reverse search) 시나리오에서 자주 사용돼요.
출처: 문서
본문
percolate 쿼리는 주어진 문서와 일치하는 저장된 쿼리를 찾아요. 이 동작은 일반 검색의 반대예요. 쿼리와 일치하는 문서를 찾는 대신, 문서와 일치하는 쿼리를 찾는 거예요. percolate 쿼리는 알림(alerting), 통지(notification), 역방향 검색(reverse search) 같은 용도에서 자주 사용돼요. percolate 쿼리를 다룰 때 다음 핵심 사항을 기억하세요:
- 인라인(inline)으로 제공된 문서를 퍼콜레이션하거나 인덱스에서 기존 문서를 가져올 수 있어요.
- 문서와 저장된 쿼리는 동일한 필드 이름과 타입을 사용해야 해요.
- 퍼콜레이션을 필터링과 점수화(scoring)와 결합해 복잡한 일치 시스템을 만들 수 있어요.
- percolate 쿼리는 비용이 많이 드는 쿼리로 간주되며, 클러스터 설정 search.allow_expensive_queries가 true(기본값)로 설정된 경우에만 실행돼요. 이 설정이 false이면 percolate 쿼리는 거부돼요. percolate 쿼리는 다양한 실시간 일치 시나리오에서 유용해요. 몇 가지 일반적인 사용 사례는 다음과 같아요:
- 전자상거래 알림: 사용자가 상품에 대한 관심을 등록할 수 있어요. 예를 들어 ‘새 Apple 노트북이 입고되면 알려줘’ 같은 거예요. 새 상품 문서가 인덱싱되면 시스템이 일치하는 저장된 쿼리를 가진 모든 사용자를 찾아 알림을 보내요.
- 구인 알림: 구직자가 선호하는 직함이나 지역을 기준으로 쿼리를 저장하고, 새 채용 공고가 이와 일치하면 알림이 발동돼요.
- 보안 및 알림 시스템: 들어오는 로그나 이벤트 데이터를 저장된 규칙이나 이상 징후 패턴에 대해 퍼콜레이션해요.
- 뉴스 필터링: 들어오는 기사를 저장된 주제 프로필과 대조해 관련 콘텐츠를 분류하거나 전달해요.
퍼콜레이션 동작 방식 (How percolation works)
- 저장된 쿼리는 특별한 percolator 필드 타입에 저장돼요.
- 문서는 모든 저장된 쿼리와 비교돼요.
- 일치하는 각 쿼리는 해당 _id와 함께 반환돼요.
- 하이라이팅이 활성화되어 있으면 일치한 텍스트 조각도 반환돼요.
- 여러 문서를 보내면 _percolator_document_slot이 일치하는 문서를 표시해요.
예제 (Example)
다음 예제는 percolate 쿼리를 저장하고 다양한 방법으로 문서를 테스트하는 방법을 보여줘요.
저장된 쿼리를 저장할 인덱스 생성
먼저 저장된 쿼리를 보관하기 위해 percolator 필드 타입으로 매핑을 구성한 인덱스를 생성하세요:
PUT /my_percolator_index
{
"mappings": {
"properties": {
"query": {
"type": "percolator"
},
"title": {
"type": "text"
}
}
}
}
title 필드에서 “apple”과 일치하는 쿼리를 추가하세요:
POST /my_percolator_index/_doc/1
{
"query": {
"match": {
"title": "apple"
}
}
}
title 필드에서 “banana”와 일치하는 쿼리를 추가하세요:
POST /my_percolator_index/_doc/2
{
"query": {
"match": {
"title": "banana"
}
}
}
인라인 문서 퍼콜레이션
인라인 문서를 저장된 쿼리들과 대조해 테스트하세요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"title": "Fresh Apple Harvest"
}
}
}
}
응답은 title 필드에 “apple”이라는 단어가 포함된 문서를 검색하는 저장된 percolate 쿼리를 반환하며, _id: 1로 식별돼요:
{
...
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
}
]
}
}
여러 문서 퍼콜레이션
같은 쿼리에서 여러 문서를 테스트하려면 다음 요청을 사용하세요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"documents": [
{ "title": "Banana flavoured ice-cream" },
{ "title": "Apple pie recipe" },
{ "title": "Banana bread instructions" },
{ "title": "Cherry tart" }
]
}
}
}
_percolator_document_slot 필드는 각 저장된 쿼리와 일치하는 각 문서를 (인덱스로) 식별하는 데 도움을 줘요:
{
...
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.54726034,
"hits": [
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.54726034,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot": [
1
]
}
},
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.31506687,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot": [
0,
2
]
}
}
]
}
}
기존 인덱싱 문서 퍼콜레이션
다른 인덱스에 이미 저장된 기존 문서를 참조해 일치하는 percolate 쿼리가 있는지 확인할 수 있어요. 문서를 위한 별도의 인덱스를 생성하세요:
PUT /products
{
"mappings": {
"properties": {
"title": {
"type": "text"
}
}
}
}
문서를 추가하세요:
POST /products/_doc/1
{
"title": "Banana Smoothie Special"
}
저장된 쿼리가 인덱싱된 문서와 일치하는지 확인하세요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"index": "products",
"id": "1"
}
}
}
저장된 문서를 사용할 때는 index와 id를 모두 제공해야 해요. 해당 쿼리가 반환돼요:
{
...
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
}
]
}
}
일괄 퍼콜레이션 (여러 문서)
하나의 요청에서 여러 문서를 확인할 수 있어요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"documents": [
{ "title": "Apple event coming soon" },
{ "title": "Banana farms expand" },
{ "title": "Cherry season starts" }
]
}
}
}
각 일치 항목은 _percolator_document_slot 필드에서 일치하는 문서를 나타내요:
{
...
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.46484798,
"hits": [
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.46484798,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot": [
1
]
}
},
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.41211313,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
}
]
}
}
명명된 쿼리를 사용한 다중 쿼리 퍼콜레이션
명명된 쿼리(named query) 안에서 서로 다른 문서를 퍼콜레이션할 수 있어요:
GET /my_percolator_index/_search
{
"query": {
"bool": {
"should": [
{
"percolate": {
"field": "query",
"document": {
"title": "Apple pie recipe"
},
"name": "apple_doc"
}
},
{
"percolate": {
"field": "query",
"document": {
"title": "Banana bread instructions"
},
"name": "banana_doc"
}
}
]
}
}
}
name 파라미터는 _percolator_document_slot에 붙어 일치하는 쿼리를 제공해요:
{
...
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot_apple_doc": [
0
]
}
},
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot_banana_doc": [
0
]
}
}
]
}
}
이 방식은 개별 문서마다 더 세부적인 사용자 지정 쿼리 로직을 구성할 수 있게 해줘요. 다음 예제에서는 첫 번째 문서에서 title 필드를, 두 번째 문서에서 description 필드를 쿼리해요. boost 파라미터도 함께 제공돼요:
GET /my_percolator_index/_search
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"percolate": {
"field": "query",
"document": {
"title": "Apple pie recipe"
},
"name": "apple_doc"
}
},
"boost": 1.0
}
},
{
"constant_score": {
"filter": {
"percolate": {
"field": "query",
"document": {
"description": "Banana bread with honey"
},
"name": "banana_doc"
}
},
"boost": 3.0
}
}
]
}
}
}
일괄 퍼콜레이션과 명명된 퍼콜레이션 비교
일괄 퍼콜레이션(documents 사용)과 명명된 퍼콜레이션(bool과 name 사용) 모두 여러 문서를 퍼콜레이션하는 데 쓸 수 있어요. 하지만 결과가 표시되고 해석되며 제어되는 방식이 달라요. 기능적으로는 유사한 결과를 제공하지만 다음 표와 같은 중요한 구조적 차이가 있어요.
Feature Batch (documents) Named (bool + percolate + name)
입력 형식 | 하나의 percolate 절, 문서 배열 | 문서당 하나씩, 여러 percolate 절
문서별 추적성 | 슬롯 인덱스(0, 1, …) 기준 | 이름(apple_doc, banana_doc) 기준
일치 슬롯 응답 필드 | _percolator_document_slot: [0] | percolator_document_slot
일치 항목 하이라이팅 (Highlighting matches)
percolate 쿼리는 일반 쿼리와 다르게 하이라이팅을 처리해요:
- 일반 쿼리에서는 문서가 인덱스에 저장되고, 검색 쿼리를 사용해 일치하는 용어를 하이라이팅해요.
- percolate 쿼리에서는 역할이 뒤집혀요. (percolator 인덱스의) 저장된 쿼리를 사용해 문서를 하이라이팅해요. 즉 document나 documents에 제공된 문서가 하이라이팅의 대상이 되고, percolate 쿼리가 하이라이팅할 부분을 결정해요.
단일 문서 하이라이팅
이 예제는 my_percolator_index에 앞서 정의한 검색을 사용해요. 다음 요청으로 title 필드에서 일치 항목을 하이라이팅하세요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"document": {
"title": "Apple banana smoothie"
}
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
일치 항목은 일치된 쿼리에 따라 하이라이팅돼요:
{
...
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.13076457,
"hits": [
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
},
"highlight": {
"title": [
"Apple banana smoothie"
]
}
},
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.13076457,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
},
"highlight": {
"title": [
"Apple banana smoothie"
]
}
}
]
}
}
여러 문서 하이라이팅
documents 배열을 사용해 여러 문서를 퍼콜레이션하면 각 문서에 슬롯 인덱스가 할당돼요. 그러면 하이라이트 키가 다음 형태를 띠게 되는데, 여기서
"_": [ ... ]
하이라이팅과 함께 두 문서를 퍼콜레이션하려면 다음 명령을 사용하세요:
POST /my_percolator_index/_search
{
"query": {
"percolate": {
"field": "query",
"documents": [
{ "title": "Apple pie recipe" },
{ "title": "Banana smoothie ideas" }
]
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
응답에는 0_title, 1_title처럼 문서 슬롯으로 접두어가 붙은 하이라이팅 필드가 포함돼요:
{
...
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0.31506687,
"hits": [
{
"_index": "my_percolator_index",
"_id": "1",
"_score": 0.31506687,
"_source": {
"query": {
"match": {
"title": "apple"
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
},
"highlight": {
"0_title": [
"Apple pie recipe"
]
}
},
{
"_index": "my_percolator_index",
"_id": "2",
"_score": 0.31506687,
"_source": {
"query": {
"match": {
"title": "banana"
}
}
},
"fields": {
"_percolator_document_slot": [
1
]
},
"highlight": {
"1_title": [
"Banana smoothie ideas"
]
}
}
]
}
}
파라미터 (Parameters)
percolate 쿼리는 다음 파라미터를 지원해요.
Parameter Required/Optional Description
field | 필수 | 저장된 percolate 쿼리가 들어 있는 필드예요.
document | 선택 | 저장된 쿼리와 대조할 단일 인라인 문서예요.
documents | 선택 | 저장된 쿼리와 대조할 여러 인라인 문서 배열이에요.
index | 선택 | 일치시키려는 문서가 들어 있는 인덱스예요.
id | 선택 | 인덱스에서 가져올 문서의 ID예요.
routing | 선택 | 문서를 가져올 때 사용할 라우팅(routing) 값이에요.
preference | 선택 | 문서를 가져올 때 샤드 라우팅의 기본 설정(preference)이에요.
name | 선택 | percolate 절에 할당된 이름이에요. bool 쿼리에서 여러 percolate 절을 사용할 때 유용해요.
ExampleCreate an index for storing saved queries
Highlighting matchesHighlighting a single document