๐ ํ๊ธ ํํ์ ๋ถ์๊ธฐ๋ก ๊ฒ์ ์ ํ๋ ๊ฐ์ ํ๊ธฐ: Nori + ์๋์์ฑ ๋ถ๋ฆฌ ์ ๋ต
๐ญ ๋ฌธ์ ์ธ์
๊ธฐ์กด์๋ ์ฑ์ฉ ๊ณต๊ณ ๊ฒ์์ ๋ถ๋ถ ๊ฒ์(N-gram)๊ณผ ์๋ ์์ฑ(Edge N-gram) ๊ธฐ๋ฅ์ ํจ๊ป ์ ์ฉํ๊ณ ์์๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ฒ์์ ๊ฐ๋ฅํ์ง๋ง, ์ฌ์ฉ์๊ฐ ๊ธฐ๋ํ๋ ์ ํํ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ์ข
์ข
๋ฐ์ํ๋ค.
๐ ์์
์ฌ์ฉ์๊ฐ "์นด๋"๋ผ๋ ๋จ์ด๋ฅผ ํฌํจํ ์ฑ์ฉ ๊ณต๊ณ ๋ฅผ ์ฐพ๊ณ ์ถ์ ๋, ์๋ ์์ฑ ๊ธฐ๋ฅ์ด ํจ๊ป ๋์ํ๋ฉด์
์นด๋ก ์์ํ๋ ์ ํ ๋ค๋ฅธ ์ฑ์ฉ ๊ณต๊ณ ๋ค๊น์ง ํจ๊ป ๊ฒ์๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.

๊ฒฐ๊ณผ์ ์ผ๋ก ์ํ๋ ๊ฒฐ๊ณผ๋ณด๋ค ๋๋ฌด ๋ง์ ๋ฐ์ดํฐ๊ฐ ํจ๊ป ๋ ธ์ถ๋๋ฉด์ ์ฌ์ฉ์๋ ์ ํํ ๊ฒ์์ด ์ด๋ ต๋ค๋ ์ธ์์ ๋ฐ๊ฒ ๋์๋ค.
๐งฑ ๊ธฐ์กด ์ธ๋ฑ์ค ๊ตฌ์กฐ์ ํ๊ณ
๊ธฐ์กด ์ธ๋ฑ์ค ์ค์ ์์๋ title, requiredSkills ๋ฑ์ ํ๋์ ๋ค์ ๋ ๋ถ์๊ธฐ๋ฅผ ํจ๊ป ์ ์ฉํ๊ณ ์์๋ค.
โ
ngram_analyzer โ ๋ถ๋ถ ๊ฒ์์ฉ
โ
autocomplete_analyzer โ ์๋ ์์ฑ์ฉ
"title": {
"type": "text",
"fields": {
"ngram": { "type": "text", "analyzer": "ngram_analyzer" },
"autocomplete": { "type": "text", "analyzer": "autocomplete_analyzer" }
}
}
๐ ์ด ๊ตฌ์กฐ๋ ๋จ์ด์ ์ผ๋ถ๋ถ๋ง ์ ๋ ฅํด๋ ๊ฒ์์ด ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ด ์์์ง๋ง, ๋ฌธ์ ๋ ๋ ๊ธฐ๋ฅ์ด ๊ฐ์ ๊ฒ์ API์์ ๋์์ ์๋ํ๋ฉด์ ๊ฒ์ ๊ฒฐ๊ณผ์ ์ ๋ฐ๋๊ฐ ํฌ๊ฒ ๋จ์ด์ง๋ ํ์์ด ๋ฐ์ํ๋ค๋ ์ ์ด๋ค.
์ฌ์ฉ์๊ฐ ์ ํํ๊ฒ ํน์ ํค์๋๋ฅผ ๊ฒ์ํ๋๋ผ๋ ์๋ ์์ฑ์ฉ ํ ํฐ์ด ํจ๊ป ์กฐํ๋๋ฉฐ ์ํ์ง ์๋ ๋ฐ์ดํฐ๊ฐ ๊ณผ๋ํ๊ฒ ํฌํจ๋๋ ๋ฌธ์ ๋ก ์ด์ด์ก๋ค.
๐ง ํด๊ฒฐ ๋ฐฉํฅ: Nori ํํ์ ๋ถ์๊ธฐ + ๊ธฐ๋ฅ ๋ถ๋ฆฌ
ํ๊ตญ์ด๋ ์์ด์ ๋ฌ๋ฆฌ ์กฐ์ฌ, ์ด๋ฏธ, ๋ณตํฉ์ด ๋ฑ ๊ตฌ์ฑ ๋ฐฉ์์ด ๋ณต์กํ๊ธฐ ๋๋ฌธ์
๋จ์ํ N-gram ๋ถ์๊ธฐ๋ง์ผ๋ก๋ ์ ํํ ์๋ฏธ ๋จ์ ๋ถ์์ ํ๊ณ๊ฐ ์๋ค.
๊ทธ๋์, ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ ๋ฐฉํฅ์ ์ค์ ํ๋ค.
โ
Nori ํํ์ ๋ถ์๊ธฐ๋ฅผ ๋์
๐ ํ๊ตญ์ด๋ฅผ ํํ์ ๋จ์๋ก ๋ถ์ํ์ฌ ๋ณด๋ค ์๋ฏธ ์ค์ฌ์ ๊ฒ์์ด ๊ฐ๋ฅํ๋๋ก ๊ฐ์
๐ "๊ฐ๋ฐ์๊ฐ" โ [๊ฐ๋ฐ, ์]
๐ ์กฐ์ฌ/์ด๋ฏธ ์ ๊ฑฐ + ์ฌ์ฉ์ ์ฌ์ ๋ฑ๋ก๋ ๊ฐ๋ฅ
โ
์๋ ์์ฑ ๊ธฐ๋ฅ์ ๋ณ๋์ API๋ก ๋ถ๋ฆฌ
๐ ๊ฒ์ ์ ๋ฐ๋์ ์ํฅ์ ์ฃผ์ง ์๋๋ก ๊ธฐ๋ฅ์ ์ฑ
์์ ๋ถ๋ฆฌ
๐ ์ ํํ ํค์๋ ๊ฒ์๊ณผ ํผ๋๋์ง ์๊ฒ ์ค๊ณ
๐งช Nori ๋ถ์๊ธฐ ์ ์ฉ
Elasticsearch์์๋ ํ๊ตญ์ด ํํ์ ๋ถ์์ ์ํด Nori ๋ถ์๊ธฐ์ Nori Tokenizer๋ฅผ ์ ๊ณตํ๋ค.
ํญ๋ชฉ | Nori ๋ถ์๊ธฐ | Nori Tokenizer |
์ญํ | ํ๊ธ ํ ์คํธ๋ฅผ ํํ์๋ก ๋ถ๋ฆฌํ๋ ์์ฑํ Analyzer | ํํ์ ๋จ์๋ก Tokenizing๋ง ์ํ |
์์ | ๋ฐฑ์๋ ๊ฐ๋ฐ์ โ [๋ฐฑ์๋, ๊ฐ๋ฐ, ์] |
์๋ฐ ๊ฐ๋ฐ์ โ [์๋ฐ, ๊ฐ๋ฐ, ์] |
๐ ์กฐ์ฌ ๋ฐ ์ด๋ฏธ ์ ๊ฑฐ, ์ฌ์ฉ์ ์ฌ์ ์ค์ , ๋ณตํฉ์ด ์ฒ๋ฆฌ ๋ฑ ๋ค์ํ ํ๊ธ ์ฒ๋ฆฌ ๊ธฐ๋ฅ ์ ๊ณต
โ๏ธ ๋ณ๊ฒฝ๋ ์ธ๋ฑ์ค ๊ตฌ์กฐ
"title": {
"type": "text",
"fields": {
"morph": {
"type": "text",
"analyzer": "nori_analyzer"
},
"autocomplete": {
"type": "text",
"analyzer": "autocomplete_analyzer"
}
}
}
๐ ํ๋ ์ค๋ช
โ
morph
๐ ์ ํํ ๊ฒ์์ ์ํ Nori ํํ์ ๊ธฐ๋ฐ ๋ถ์ ์ ์ฉ
๐ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ํค์๋๋ฅผ ์๋ฏธ ๋จ์๋ก ํด์ํ์ฌ ์ ๋ฐํ ๊ฒ์ ๊ฐ๋ฅ
โ
autocomplete
๐ ์๋ ์์ฑ์ ์ํ Edge-Ngram ๋ถ์๊ธฐ ์ ์ฉ
๐ ์
๋ ฅ๊ฐ์ ์๋ถ๋ถ์ ๊ธฐ์ค์ผ๋ก ์๋ ์์ฑ ๊ฒ์ ์ ๊ณต
๐ ์ด ์ค์ ์ผ๋ก ํ๊ธ ํ ์คํธ๋ ์๋ฏธ ๋จ์๋ก ์ ํํ๊ฒ ๊ฒ์ํ ์ ์๊ณ , ์๋ ์์ฑ ๊ธฐ๋ฅ์ ๋ณ๋ API๋ก ๋ถ๋ฆฌ๋์ด ๊ฒ์ ๊ฒฐ๊ณผ์ ์ํฅ์ ์ฃผ์ง ์๋๋ก ๋ถ๋ฆฌ ์ค๊ณ๋์๋ค.
๐ ์๋์์ฑ ๊ธฐ๋ฅ ๋ถ๋ฆฌ ๋ฐ ๊ฐ์
์๋์์ฑ ๊ธฐ๋ฅ์ Edge N-gram ํํฐ๋ฅผ ํ์ฉํ์ฌ ์ ๋ ฅํ ๋จ์ด์ ์๋ถ๋ถ๋ง์ผ๋ก๋ ๊ฒ์์ด ๊ฐ๋ฅํ๊ฒ ๊ตฌํํ๋ค.
"filter": {
"edge_ngram_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 25
}
}
๐ ์์
"ํ๋ก ํธ์๋ ๊ฐ๋ฐ์" โ ["ํ", "ํ๋ก ", "ํ๋ก ํธ", "ํ๋ก ํธ์", "ํ๋ก ํธ์๋"] ๋ก ๋ถํด
โ
์ฌ์ฉ์๊ฐ "ํ๋ก "๋ง ์
๋ ฅํด๋ "ํ๋ก ํธ์๋ ๊ฐ๋ฐ์"๊ฐ ํฌํจ๋ ์ฑ์ฉ ๊ณต๊ณ ๊ฐ ์๋์ผ๋ก ์ถ์ฒ๋๋ค!
โ๏ธ ๊ธฐ๋ฅ ๋ถ๋ฆฌ๋ก ์ ํ๋ ํ๋ณด
์ด์ ์๋ ์๋ ์์ฑ ํ๋๊ฐ ์ผ๋ฐ ๊ฒ์๊ณผ ํจ๊ป ๋์ํ๋ฉด์ ์ํ์ง ์๋ ๊ฒฐ๊ณผ๊ฐ ํจ๊ป ์กฐํ๋๋ ๋ฌธ์ ๊ฐ ์์๋ค.
์ด๋ฒ ๊ฐ์ ์์๋ ์๋ ์์ฑ ๊ธฐ๋ฅ์ ๋ณ๋์ API๋ก ๋ถ๋ฆฌํ์ฌ ์ ํํ ํค์๋ ๊ฒ์ ๊ฒฐ๊ณผ์ ํผํฉ๋์ง ์๋๋ก ์ฒ๋ฆฌํ๋ค.
โ ๊ฒฐ๊ณผ ๋ฐ ํ์ธ
๐ ๊ฐ์ ์ ์ฉ ํ, ๊ธฐ๋ฅ์ ๊ฐ๊ฐ์ ๋ชฉ์ ์ ๋ง๊ฒ ๋ช ํํ๊ฒ ๋ถ๋ฆฌ๋์ด ๋์ํ๋ค.
๐ ์ผ๋ฐ ๊ฒ์ (Nori ๋ถ์๊ธฐ ์ ์ฉ)
๐ "์นด๋" ํค์๋๋ก ๊ฒ์ ์ ์ ํํ "์นด๋"๋ฅผ ํฌํจํ๋ ์ฑ์ฉ ๊ณต๊ณ ๋ง ์กฐํ

โจ ์๋์์ฑ (Edge-Ngram)
๐ "์นด"๋ง ์
๋ ฅํด๋ "์นด๋", "์นด์นด์ค" ๋ฑ ๊ด๋ จ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณต


์ด์ ๋ ๊ฒ์๊ณผ ์๋ ์์ฑ์ด ์๋ก ๋ฐฉํดํ์ง ์๊ณ , ๊ฐ์์ ์ญํ ์ ์ถฉ์คํ๊ฒ ๋์ํ๋ค!
โ ํ๊ณ
์ด๋ฒ ์์ ์ ํตํด ํ๊ธ ๊ฒ์ ํ๊ฒฝ์์๋ ์ ํ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ชจ๋ ๊ณ ๋ คํ ๊ฒ์ ๊ตฌ์กฐ๋ฅผ ์ค๊ณํ๊ณ ๊ตฌํํ ์ ์์๋ค.
๐ก ํต์ฌ ์ ๋ฆฌ
โ
ํํ์ ๋ถ์(Nori) + ์๋์์ฑ(Edge-Ngram)
โ
๊ฒ์ ๋ชฉ์ ๋ณ ํ๋ ๋ถ๋ฆฌ + ๊ธฐ๋ฅ API ๋ถ๋ฆฌ
์ด๋ฒ ๊ฒฝํ์ ํตํด Elasticsearch์ ์ ์ฐํ ์ธ๋ฑ์ค ์ค๊ณ์ ํ์ฅ์ฑ ๋์ ๊ฒ์ ๊ธฐ๋ฅ์ ์ง์ ๋ค๋ค๋ณด๋ฉด์ ์ค์ ๊ฐ๊ฐ๋ ํค์ธ ์ ์์๋ค.
์์ผ๋ก๋ ๋ค์ํ ํ
์คํธ ๊ธฐ๋ฐ ๊ธฐ๋ฅ์์ ์ธ์ด ํน์ฑ๊ณผ ๊ฒ์ ๋ชฉ์ ์ ๋ง๋ ๊ตฌ์กฐ ์ค๊ณ๊ฐ ์ผ๋ง๋ ์ค์ํ์ง ๋ ๊น์ด ๊ณ ๋ฏผํ๊ฒ ๋ ๊ฒ ๊ฐ๋ค.