반응형
Re-Index
막상 이모티콘 검색을 해보니 각 원문에서 이모티콘이 얼마나 포함되어 있는지, 어떤 이모티콘이 가장 많이 있는지 검색해보자
그전에 사전 준비 작업으로 text field로 들어간 데이터에서 키워드를 추출(Es 내부에서는 Term)할 수 있도록 인덱스를 구성하고 전체 문서에서 키워드 빈도수를 기준으로 데이터를 추출하는 방법을 찾아봅니다.
인덱스 구성
PUT /mbti_term
{
"settings": {
"analysis": {
"analyzer": {
"nori_mixed": {
"tokenizer": "nori_t_mixed",
"filter": "shingle"
},
"nori_pos_noun": {
"type": "custom",
"tokenizer": "nori_t_mixed",
"filter": "pos_filter"
}
},
"tokenizer": {
"nori_t_mixed": {
"type": "nori_tokenizer",
"decompound_mode": "mixed"
}
},
"filter": {
"pos_filter": {
"type": "nori_part_of_speech",
"stoptags": [
"VV", "VA", "VX", "VCP", "VCN", "MM", "MAG", "MAJ",
"IC", "J", "E",
"XPN", "XSA", "XSN", "XSV",
"SP", "SSC", "SSO", "SC", "SE",
"UNA"
]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text"
},
"contents": {
"type": "text",
"fields": {
"full": {
"type": "keyword"
},
"nori_mixed": {
"type": "text",
"analyzer": "nori_mixed",
"search_analyzer": "standard",
"fielddata": true,
"term_vector": "yes"
},
"nori_noun": {
"type": "text",
"analyzer": "nori_pos_noun",
"search_analyzer": "standard",
"fielddata": true,
"term_vector": "yes"
}
},
"fielddata": true,
"term_vector": "yes"
},
"keyword": {
"type": "keyword"
},
"platform": {
"type": "keyword"
},
"published_at": {
"type": "date"
},
"doc_url": {
"type": "text"
},
"comment_cnt": {
"type": "integer"
},
"like_cnt": {
"type": "integer"
}
}
}
}
여기서 핵심은 대상 필드에서 term_vector,fielddata 이다.
"contents": {
"type": "text",
"fields": {
"full": {
"type": "keyword"
},
"nori_mixed": {
"type": "text",
"analyzer": "nori_mixed",
"search_analyzer": "standard",
"fielddata": true,
"term_vector": "yes"
},
"nori_noun": {
"type": "text",
"analyzer": "nori_pos_noun",
"search_analyzer": "standard",
"fielddata": true,
"term_vector": "yes"
}
},
"fielddata": true,
"term_vector": "yes"
}
이를 바탕으로 문서에 있는 단어(term)의 수를 계산하는 쿼리를 보면 아래와 같다.
GET mbti_term/_search
{
"size": 0,
"aggs": {
"term_cnt": {
"terms": {
//contents.nori_mixed, contents.nori_noun 등으로도 가능
"field": "contents",
"size": 1000
}
}
}
}
여기에 단어의 길이로 정렬하여 목록을 출력하는 방법도 있다. - 링크 (하지만 502 Bad Gateway 에러가 발생한다..)
위의 쿼리에 대한 결과는 아래와 같다.
{
"took" : 555,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000,
"relation" : "gte"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"term_cnt" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 11058130,
"buckets" : [
{
"key" : "이",
"doc_count" : 15136
},
{
"key" : "하",
"doc_count" : 15088
},
{
"key" : "는",
"doc_count" : 14448
},
{
"key" : "ᆫ",
"doc_count" : 13909
},
{
"key" : "고",
"doc_count" : 13348
},
{
"key" : "아",
"doc_count" : 13032
},
{
"key" : "은",
"doc_count" : 13015
},
{
"key" : "가",
"doc_count" : 12940
},
이모티콘 필드 구성
본문에서 어떻게 이모티콘만 추출할 수 있을까?
아래 쿼리를 사용하면 이모티콘이 포함된 본문만 추출할 수 있다.
GET mbti_term/_search
{
"query": {
"regexp": {
"contents": "[\\uD83D\\uDE00-\\uD83D\\uDE4F, \\uD83C\\uDF00-\\uD83D\\uDDFF, \\uD83D\\uDE80-\\uD83D\\uDEFF, \\uD83C\\uDDE0-\\uD83C\\uDDFF]"
}
}
}
콘텐츠에서 이모티콘이 포함된 콘텐츠만 추출하는 것을 완료했습니다. 하지만 이모티콘만 별도의 필드로 저장해서 분석할 수 있도록 분류하는 게 필요할 것 같습니다.
다음에는 실제 인덱스 필드에 이모티콘 값만 저장될 수 있도록 하는 인덱스 구성을 진행해보겠습니다.
반응형
'Elastic Search' 카테고리의 다른 글
[Elastic Search] MBTI 검색 프로젝트 - 3. API 구축하기 (0) | 2022.04.29 |
---|---|
[Elastic Search] MBTI 검색 프로젝트 - 2. Emoji 검색 및 Aggregation(2편) (0) | 2022.04.21 |
[Elastic Search] MBTI 검색 프로젝트 - 2. Emoji 검색 및 Aggregation (0) | 2022.04.13 |
[Elastic Search] MBTI 검색 프로젝트 - 1. 검색 Score 튜닝 (0) | 2022.04.12 |
[Elastic Search] 검색 구현하기(with Fast API) (0) | 2022.02.15 |