엘라스틱 서치에서 일반적인 검색 기능은 특정 인덱스에 문서를 저장하고, 쿼리에 매칭되는 문서를 불러오는 방식으로 수행된다.

하지만 percolating 쿼리 방식은 그 반대로 동작한다. 쿼리를 사전에 저장하고, 새로 유입된 문서가 매칭되는 쿼리가 있는지 확인해 매칭되는 쿼리를 반환한다.

업무적으로 필요한 기능이어서 알아보던 중 알게되어서 정리해본다.

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-percolate-query.html



인덱스 생성

아래 인덱스생성에 보면 두 가지 필드를 볼 수있다. 먼저 message 필드는 percolator에서 정의된 문서를 임시 인덱스로 인덱싱하기 전에 사전 처리하는 데 사용되는 필드이다. query 필드는 쿼리 문서를 인덱싱하는 데 사용된다. 실제 Elasticsearch 쿼리를 나타내는 json 객체를 보유한다. query 필드는 쿼리 dsl을 이해하고 이후에 percolate 쿼리에 정의 된 문서와 일치시키기 위해 쿼리를 저장한다.

이해하기 어려운데, 자세한 내용은 사용방법을 더 보면 알 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUT wedul_product
{
  "mappings": {
    "seat": {
      "properties": {
        "message": {
          "type": "text"
        },
        "query": {
          "type": "percolator"
        }
      }
    }
  }
}
 
cs


쿼리 삽입
상품명을 가지고 있는 문서에서 특정 지역들에 대한 정보가 들어있는지 확인하기 위해서 지역정보 쿼리를 미리 넣어둔다. (춘천, 서울, 등등...)

1
2
3
4
5
6
7
8
POST /wedul_product/seat/?refresh
{
    "query" : {
        "match" : {
            "message" : "춘천"
        }
    }
}
cs



문서 매칭되는 쿼리 찾아보기
'위들아이패드 서울 지점'과 '맥북 부산시 AS 지점' 두 개를 검색해보고 매칭 결과를 확인해보자. 쿼리는 score를 고려하는 것과 percolate를 사용해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#쿼리 (score 없는 filter 사용)
GET /wedul_product/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "percolate": {
          "field": "query",
          "document": {
            "message": "위들아이패드 서울 지점"
          }
        }
      }
    }
  }
}
 
#결과
{
  "took": 55,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "wedul_product",
        "_type": "seat",
        "_id": "7dAz8mUBIvIDO7uZfj1s",
        "_score": 1,
        "_source": {
          "query": {
            "match": {
              "message": "서울"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        }
      }
    ]
  }
}
 
# score가 고려된 percolate사용
GET /wedul_product/_search
{
  
  "query" : {
        "percolate" : {
            "field": "query",
            "document" : {
                "message" : "맥북 부산 시 AS 지점"
            }
        }
    }
}
 
#결과
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "wedul_product",
        "_type": "seat",
        "_id": "BtAz8mUBIvIDO7uZkz5Q",
        "_score": 0.2876821,
        "_source": {
          "query": {
            "match": {
              "message": "부산"
            }
          }
        },
        "fields": {
          "_percolator_document_slot": [
            0
          ]
        }
      }
    ]
  }
}
cs


이를 이용해서 다양한 것을 할 수 있을 것 같다.

네이버에서도 이 기능을 이용해서 로그 알림 기능을 만들었다. 참고하면 좋을 것 같다.
https://d2.naver.com/helloworld/1044388

+ Recent posts