92개국이 평창 동계올림픽대회에 참가했고, 49개국이 동계패럴림픽대회에 참가했습니다. Elastic은 34개국에 직원이 있습니다. 각국의 사람들이 각자의 언어로 메일을 씁니다. 그중에서 한글로 “올림픽대회”라는 키워드가 들어 있는 메일을 찾으려고 합니다.
https://www.elastic.co/guide/en/elasticsearch/guide/current/language-intro.html에 여러 가지 언어로 작성된 문서를 처리하는 몇 가지 방법이 나와 있습니다만 대부분 커스텀 플러그인이 필요 없는 유럽 언어를 예로 들고 있습니다. 이 문서는 한국어, 일본어, 중국어용 커스텀 플러그인(형태소 분석기)를 소개하고 멀티필드를 이용한 다중 언어 텍스트 검색 방법을 알아봅니다.
Standard Analyzer: 기본(default) 분석기
전문 검색에는 형태소 분석기가 필요합니다. 기본 분석기는 standard analyzer로, 한국어, 중국어, 일본어 검색에는 적합하지 않습니다. 다음은 standard analyzer로 한국어, 중국어, 일본어 텍스트를 분석한 결과입니다. 텍스트는 https://www.pyeongchang2018.com/ko/about-the-games에서 발췌했습니다.
[한국어]
POST _analyze
{
"analyzer": "standard",
"text": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다."
}
=>
{
"tokens": [
{
"token": "제23회",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "동계올림픽대회는",
"start_offset": 5,
"end_offset": 13,
"type": "<HANGUL>",
"position": 1
},
…
한국어는 교착어로 명사(예: “동계올림픽대회”) 뒤에 흔히 조사(예: “는”)가 붙습니다. 검색을 위해서는 조사를 제거해야 하지만 standard analyzer는 명사와 조사를 분리하지 않습니다.
[일본어]
POST _analyze
{
"analyzer": "standard",
"text": "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。"
}
=>
{
"tokens": [
{
"token": "第",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "23",
"start_offset": 1,
"end_offset": 3,
"type": "<NUM>",
"position": 1
},
{
"token": "回",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "冬",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "季",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 4
},
{
"token": "オリンピック",
"start_offset": 6,
"end_offset": 12,
"type": "<KATAKANA>",
"position": 5
},
{
"token": "大",
"start_offset": 12,
"end_offset": 13,
"type": "<IDEOGRAPHIC>",
"position": 6
},
{
"token": "会",
"start_offset": 13,
"end_offset": 14,
"type": "<IDEOGRAPHIC>",
"position": 7
},
{
"token": "は",
"start_offset": 14,
"end_offset": 15,
"type": "<HIRAGANA>",
"position": 8
},
…
일본어도 교착어로 명사(예: “冬季オリンピック大会”) 뒤에 조사(예: “は”)가 붙습니다. 검색을 위해서는 역시 조사를 제거해야 하지만 standard analyzer는 명사와 조사를 분리하지 않습니다. 설상가상으로 일본어 문장은 한자와 가나로 이루어져 있는데 standard analyzer는 한자 하나하나를 토큰으로 만들어 버립니다.
[중국어]
POST _analyze
{
"analyzer": "standard",
"text": "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。"
}
=>
{
"tokens": [
{
"token": "第",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "23",
"start_offset": 1,
"end_offset": 3,
"type": "<NUM>",
"position": 1
},
{
"token": "届",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "冬",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "季",
"start_offset": 5,
"end_offset": 6,
"type": "<IDEOGRAPHIC>",
"position": 4
},
{
"token": "奥",
"start_offset": 6,
"end_offset": 7,
"type": "<IDEOGRAPHIC>",
"position": 5
},
{
"token": "运",
"start_offset": 7,
"end_offset": 8,
"type": "<IDEOGRAPHIC>",
"position": 6
},
{
"token": "会",
"start_offset": 8,
"end_offset": 9,
"type": "<IDEOGRAPHIC>",
"position": 7
},
...
역시나 standard analyzer는 “冬季奥运会”를 “동계올림픽”이라는 단어로 인식하지 못하고 글자단위로 모두 나누어 버립니다.
언어별 분석기: 커스텀 플러그인
언어별 분석기를 사용하면 보다 나은 검색 결과를 얻을 수 있습니다. 유명한 한국어, 일본어, 중국어용 분석기로는 각각 openkoreantext-analyzer, kuromoji, smartcn이 있습니다. 아래 예들을 실행하기 전에 모든 노드에 설치해야 합니다. openkoreantext-analyzer는 Elastic 리포지토리에 없기 때문에 설치할 때 전체 URL을 적거나 미리 다운로드해야 합니다.
[한국어]
POST _analyze
{
"analyzer": "openkoreantext-analyzer",
"text": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다."
}
=>
{
"tokens": [
{
"token": "제",
"start_offset": 0,
"end_offset": 1,
"type": "Noun",
"position": 0
},
{
"token": "23회",
"start_offset": 1,
"end_offset": 4,
"type": "Number",
"position": 1
},
{
"token": "동계올림픽",
"start_offset": 5,
"end_offset": 10,
"type": "Noun",
"position": 2
},
{
"token": "대회",
"start_offset": 10,
"end_offset": 12,
"type": "Noun",
"position": 3
},
...
이제 조사가 모두 제거되었습니다.
[일본어]
POST _analyze
{
"analyzer": "kuromoji",
"text": "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。"
}
=>
{
"tokens": [
{
"token": "第",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 0
},
{
"token": "23",
"start_offset": 1,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "回",
"start_offset": 3,
"end_offset": 4,
"type": "word",
"position": 2
},
{
"token": "冬季",
"start_offset": 4,
"end_offset": 6,
"type": "word",
"position": 3
},
{
"token": "オリンピック",
"start_offset": 6,
"end_offset": 12,
"type": "word",
"position": 4
},
{
"token": "大会",
"start_offset": 12,
"end_offset": 14,
"type": "word",
"position": 5
},
...
역시 조사가 제거되고 한자가 단어 단위로 토큰화되었습니다.
[중국어]
POST _analyze
{
"analyzer": "smartcn",
"text": "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。"
}
=>
{
"tokens": [
{
"token": "第",
"start_offset": 0,
"end_offset": 1,
"type": "word",
"position": 0
},
{
"token": "23",
"start_offset": 1,
"end_offset": 3,
"type": "word",
"position": 1
},
{
"token": "届",
"start_offset": 3,
"end_offset": 4,
"type": "word",
"position": 2
},
{
"token": "冬季",
"start_offset": 4,
"end_offset": 6,
"type": "word",
"position": 3
},
{
"token": "奥运会",
"start_offset": 6,
"end_offset": 9,
"type": "word",
"position": 4
},
...
역시 “冬季”와 “奥运会”가 단어 단위로 토큰화되었습니다.
이제 한국어, 중국어, 일본어 문장을 분석할 수 있게 되었습니다. 엘라스틱서치 6.2를 이용한 한국어, 중국어, 일본어 검색 - 2부: Multi-fields에서는 multi-fields를 이용해서 한중일어 문장을 인덱싱하고 검색하는 예를 살펴보겠습니다.