How to Search Chinese, Japanese, and Korean Text with Elasticsearch 6.2 - Part 3: Language Detector
This is Part 3 of my series on searching Chinese, Japanese, and Korean text. If you haven't read Part 1 about Analyzers, you may want to start there. If you have, How to Search Chinese, Japanese, and Korean Text with Elasticsearch 6.2 - Part 2: Multi-fields introduced multi-fields to index and search documents written in multiple languages. However, it may be a waste of time and storage to store a text in four fields and analyze it with four analyzers regardless of its language. Now we’ll try to optimize using a language detector. Again, the texts are excerpts from https://www.pyeongchang2018.com/en/about-the-games
Language Detector
We can install and utilize an ingest plugin for language detection to try to save time and storage. Instead of indexing into the main field and three sub-fields, the following ingest pipeline detects the language of the “body” field and put the detected language into the “language” field using the langdetect processor. Then the script processor copies the content of the “body” field to a language-specific field (english_field, korean_field, japanese_field, or chinese_field) for the analysis.
PUT _ingest/pipeline/langdetect-pipeline { "description": "A pipeline to do whatever", "processors": [ { "langdetect": { "field": "body", "target_field": "language" } }, { "script": { "lang": "painless", "source": "if (ctx.language == 'ko') ctx.korean_field = ctx.body; if (ctx.language == 'ja') ctx.japanese_field = ctx.body; if (ctx.language == 'zh-cn') ctx.chinese_field = ctx.body; if (ctx.language == 'en') ctx.english_field = ctx.body;" } } ] }
I’m using kuromoji, smartcn, and openkoreantext-analyzer for this blog post and you should install them before creating the following index.
DELETE test2 PUT /test2 { "mappings": { "docs": { "properties": { "body": { "type": "text" }, "english_field": { "type": "text" }, "korean_field": { "analyzer": "openkoreantext-analyzer", "type": "text" }, "japanese_field": { "analyzer": "kuromoji", "type": "text" }, "chinese_field": { "analyzer": "smartcn", "type": "text" } } } } }
When you index documents, you should specify the langdetect-pipeline
pipeline to use the language detector.
PUT /test2/docs/1?pipeline=langdetect-pipeline { "body" : "The XXIII Olympic Winter Games will be held for 17 days from 9 to 25 February 2018 in PyeongChang, Gangwon Province, the Republic of Korea. PyeongChang was selected as the host city of the 2018 Olympic Winter Games after receiving a majority vote at the 123rd IOC Session held on 6 July 2011 after three consecutive bids. The Olympic Winter Games will be held in Korea for the first time in 30 years after the Seoul Olympic Games in 1988. PyeongChang will be the stage for the Opening and Closing Ceremonies and most snow sports. Alpine speed events will take place in Jeongseon, and all ice sports will be competed in the coastal city of Gangneung." } PUT /test2/docs/2?pipeline=langdetect-pipeline { "body" : "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다." } PUT /test2/docs/3?pipeline=langdetect-pipeline { "body" : "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。" } PUT /test2/docs/4?pipeline=langdetect-pipeline { "body" : "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。" }
Example: If the content of the “body” field is is Korean, it is copied to the korean_field
as below:
GET /test2/docs/2 => { "_index": "test", "_type": "docs", "_id": "2", "_version": 1, "found": true, "_source": { "language": "ko", "body": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다.", "korean_field": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다." } }
We can get the similar query result as the multi-fields case. Source filtering was used to filter the result:
Korean
POST /test2/_search { "query": { "multi_match": { "query": "올림픽대회", "fields": [ "english_field", "korean_field", "chinese_field", "japanese_field" ] } }, "_source": "body" } => ... "hits": { "total": 1, "max_score": 0.57860667, "hits": [ { "_index": "test", "_type": "docs", "_id": "2", "_score": 0.57860667, "_source": { "body": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다." } } ] } }
English
POST /test2/_search { "query": { "multi_match": { "query": "Olympic Games", "fields": [ "english_field", "korean_field", "chinese_field", "japanese_field" ] } }, "_source": "body" } => ... "hits": { "total": 1, "max_score": 0.97953933, "hits": [ { "_index": "test", "_type": "docs", "_id": "1", "_score": 0.97953933, "_source": { "body": "The XXIII Olympic Winter Games will be held for 17 days from 9 to 25 February 2018 in PyeongChang, Gangwon Province, the Republic of Korea. PyeongChang was selected as the host city of the 2018 Olympic Winter Games after receiving a majority vote at the 123rd IOC Session held on 6 July 2011 after three consecutive bids. The Olympic Winter Games will be held in Korea for the first time in 30 years after the Seoul Olympic Games in 1988. PyeongChang will be the stage for the Opening and Closing Ceremonies and most snow sports. Alpine speed events will take place in Jeongseon, and all ice sports will be competed in the coastal city of Gangneung." } } ] } }
Japanese
POST /test2/_search { "query": { "multi_match": { "query": "オリンピック大会", "fields": [ "english_field", "korean_field", "chinese_field", "japanese_field" ] } }, "_source": "body" } => ... "hits": { "total": 1, "max_score": 0.7469032, "hits": [ { "_index": "test2", "_type": "docs", "_id": "4", "_score": 0.7469032, "_source": { "body": "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。" } } ] } }
Chinese
POST /test2/_search { "query": { "multi_match": { "query": "奥运会", "fields": [ "english_field", "korean_field", "chinese_field", "japanese_field" ] } }, "_source": "body" } => ... "hits": { "total": 1, "max_score": 0.49148652, "hits": [ { "_index": "test2", "_type": "docs", "_id": "3", "_score": 0.49148652, "_source": { "body": "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。" } } ] } }
Note that we get only Japanese documents when we query with the Japanese keyword and Chinese documents when we query with the Chinese keyword because we search only fields analyzed with the language-specific analyzers. This is different from the multi-fields approach in How to Search Chinese, Japanese, and Korean Text with Elasticsearch 6.2 - Part 2: Multi-fields
Concerned with Time?
If you are concerned with time to index or query, indexing using multi-fields or the language detector takes a bit more time than single field but they don’t have much difference.
Fig. 1 - Time to index 500 documents (MacBook Pro, 2.9 GHz Intel Core i7, 16GB 2133 MHz LPDDR3)
Querying using multi-fields or the language detector takes almost the same time as single field.
Fig. 2 - Time to query 500 times (MacBook Pro, 2.9 GHz Intel Core i7, 16GB 2133 MHz LPDDR3)
With the language detector, we can get better search results and save storage than the multi-field approach. Elasticsearch 6.x even has “Sparse Field Improvements" (see Space Saving Improvements in Elasticsearch 6.0).
Appendix
- index.sh - Script to measure indexing time
- query.sh - Script to measure query time