프로젝트 진행 중 가장 큰 고민은, 단순 match가 아닌, 어떻게 하면 정보를 정확하고 유사하게 뿌려줄까? 라는 고민이었다.
- attraction_name : 가장 높은 가산치를 줘야 할 것 같다.
- wiki_title match 점수
- 공공데이터의 description : 그 다음 높은 가산치
- wiki의 description : 낮은 가산치
검색어가 있을 것이다. 단일 검색어든 뭐든..
일단 content_id로 한번에 묶으려고 한다.
검색어가 '서울 남산공원' 이라면 우리의 데이터는 '서울' 과 '남산공원' 이 같은 contend_id로 묶여있기 때문.
이 content_id는 기본 베이스인 공공데이터의 id 번호이다
script를 써야 할 것 같은데, 먼저 content_id로 묶을 것이다.
여러 Document들 중 같은 content_id로 묶은 다음, 각 도큐먼트마다 필드값을 합치고, 이 안에서 용어를 검색할 경우 정확도가 높을 것이다.
집계 로직
#먼저 content_id로 집계하자.
GET scrap_wiki_1107/_search
{
"size": 0,
"track_total_hits": true,
"aggs": {
"by_content_id": {
"terms": {
"field": "content_id",
"size": 10
}
}
}
}
# 모든 필드 합산
GET scrap_wiki_1107/_search
{
"size": 0,
"track_total_hits": true,
"aggs": {
"by_content_id": {
"terms": {
"field": "content_id",
"size": 100000 #충분히 큰 크기를 사용
},
"aggs": {
"combined_fields": {
"scripted_metric": {
"init_script": "state.messages = []",
"map_script": "state.messages.add(doc['attraction_name'].value + ' ' + doc['wiki_title'].value + ' ' + doc['wiki_content'].value + ' ' + doc['overview'].value)",
"combine_script": "return state.messages",
"reduce_script": "return states.flatten()"
}
}
}
}
}
}
하지만 중간에 value가 null인 문서가 존재했다. 이를 위해 value를 확인하는 로직을 추가해야 한다.
# map script를 다음과 같이 수정
"map_script":
"String attraction = doc['attraction_name'].size() != 0 ?
doc['attraction_name'].value : '';
String wikiTitle = doc['wiki_title'].size() != 0 ?
doc['wiki_title'].value : '';
String wikiContent = doc['wiki_content'].size() != 0 ?
doc['wiki_content'].value : '';
String overview = doc['overview'].size() != 0 ?
doc['overview'].value : '';
state.messages.add(attraction + ' ' + wikiTitle + ' ' + wikiContent + ' ' + overview)"
# 최종 수정 코드
GET scrap_wiki_1107/_search
{
"size": 0,
"track_total_hits": true,
"aggs": {
"by_content_id": {
"terms": {
"field": "content_id",
"size": 100000
},
"aggs": {
"combined_fields": {
"scripted_metric": {
"init_script": "state.messages = []",
"map_script":
"""String attraction = doc['attraction_name'].size() != 0 ?
doc['attraction_name'].value : '';
String wikiTitle = doc['wiki_title'].size() != 0 ?
doc['wiki_title'].value : '';
String wikiContent = doc['wiki_content'].size() != 0 ?
doc['wiki_content'].value : '';
String overview = doc['overview'].size() != 0 ?
doc['overview'].value : '';
state.messages.add(attraction + ' ' + wikiTitle + ' ' + wikiContent + ' ' + overview)""",
"combine_script": "return state.messages",
"reduce_script": "List combined = new ArrayList(); for (List state : states) { combined.addAll(state); } return combined;"
}
}
}
}
}
}
'프로젝트 > 여행지 오픈 API' 카테고리의 다른 글
[정리]analyzer를 사용한 수집 정보의 유사성 계산 (0) | 2023.11.09 |
---|---|
ES 서버 Nginx 설정(xpack 보안 설정) (2) | 2023.11.08 |
[ElasticSearch] MySQL Like와의 검색 속도 비교 (0) | 2023.11.07 |
[ElasticSearch] 집계함수 정의와 적용 (0) | 2023.11.06 |
[ElasticSearch] Script 쿼리와 Must 쿼리 (0) | 2023.11.03 |