Intro::
Elasticsearch์ ๊ฒ์ ๊ธฐ๋ฅ์ ๋ํ ์ ๋ฐ์ ์ธ ๋ด์ฉ์ ์์๋ด ์๋ค.
ย
ํ ํ ์คํธ ์ฟผ๋ฆฌ - Full Text Query
match_all
// ์๋ ๋ ์ฟผ๋ฆฌ๋ ๋์ผํ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค. GET my_index/_search GET my_index/_search { "query":{ "match_all":{ } } }
ย
match
ํ ํ
์คํธ ๊ฒ์์์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ฟผ๋ฆฌ์ด๋ค.
match ๊ฒ์์ ์ฌ๋ฌ ๊ฐ์ ๊ฒ์์ด๋ฅผ ์ง์ด๋ฃ๊ฒ ๋๋ฉด ๋ํดํธ๋ก OR ์กฐ๊ฑด์ผ๋ก ๊ฒ์์ด ๋์ด ์
๋ ฅ๋ ๊ฒ์์ด ๋ณ๋ก ํ๋๋ผ๋ ํฌํจ๋ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋ชจ๋ ๊ฒ์ํฉ๋๋ค. ์ด๋ operator ์ต์
์ ์ฌ์ฉํด ๊ฒ์ ์กฐ๊ฑด์ AND๋ก ๋ฐ๊ฟ ์ ๋ ์์ต๋๋ค.
GET my_index/_search { "query": { "match": { "message": "quick dog", "operator": "and" } } }
ย
match_phrase
์ ํํ ์ผ์นํ๋ ๋ด์ฉ์ ๊ฒ์ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ์ฟผ๋ฆฌ์ด๋ค. match_phrase๋ ์
๋ ฅ๋ ๊ฒ์์ด๋ฅผ ์์๊น์ง ๊ณ ๋ คํ์ฌ ๊ฒ์์ ์ํํ๋ค.
GET my_index/_search { "query": { "match_phrase": { "message": "lazy dog", "slop": 1// ์ง์ ๋ ๊ฐ ๋งํผ ๋จ์ด ์ฌ์ด์ ๋ค๋ฅธ ๊ฒ์์ด๊ฐ ๋ผ์ด๋๋ ๊ฒ์ ํ } } }
ย
query_string
๋ฉ์ธ์ง ํ๋์์ ๋ํ๋จผํธ๋ฅผ ๊ฒ์ํ๋ ์ฟผ๋ฆฌ์
๋๋ค.
GET my_index/_search { "query": { "query_string": { "default_field": "message", "query": "(jumping AND lazy) OR \"quick dog\"" } } }
ย
Bool ๋ณตํฉ ์ฟผ๋ฆฌ - Bool Query
์์ query_string ์ฟผ๋ฆฌ๋ ์ฌ๋ฌ ์กฐ๊ฑด์ ์กฐํฉํ๊ธฐ์๋ ์ฉ์ดํ ๋ฌธ๋ฒ์ด์ง๋ง ์ต์
์ด ํ์ ๋์ด ์์ต๋๋ค. ๋ณธ๋ฌธ ๊ฒ์์์ ์ฌ๋ฌ ์ฟผ๋ฆฌ๋ฅผ ์กฐํฉํ๊ธฐ ์ํด์๋ ์์์ bool ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ ๊ทธ ์์ ๋ค๋ฅธ ์ฟผ๋ฆฌ๋ค์ ๋ฃ๋ ์์ผ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค. bool ์ฟผ๋ฆฌ๋ ๋ค์์ 4๊ฐ์ ์ธ์๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ ๊ทธ ์ธ์ ์์ ๋ค๋ฅธ ์ฟผ๋ฆฌ๋ค์ ๋ฐฐ์ด๋ก ๋ฃ๋ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค.
ย
- must : ์ฟผ๋ฆฌ๊ฐ ์ฐธ์ธ ๋ํ๋จผํธ๋ค์ ๊ฒ์ํฉ๋๋ค.
- must_not : ์ฟผ๋ฆฌ๊ฐ ๊ฑฐ์ง์ธ ๋ํ๋จผํธ๋ค์ ๊ฒ์ํฉ๋๋ค.
- should : ๊ฒ์ ๊ฒฐ๊ณผ ์ค ์ด ์ฟผ๋ฆฌ์ ํด๋นํ๋ ๋ํ๋จผํธ์ ์ ์๋ฅผ ๋์ ๋๋ค.
- filter : ์ฟผ๋ฆฌ๊ฐ ์ฐธ์ธ ๋ํ๋จผํธ๋ฅผ ๊ฒ์ํ์ง๋ง ์ค์ฝ์ด๋ฅผ ๊ณ์ฐํ์ง ์์ต๋๋ค. must ๋ณด๋ค ๊ฒ์ ์๋๊ฐ ๋น ๋ฅด๊ณ ์บ์ฑ์ด ๊ฐ๋ฅํฉ๋๋ค.
ย
GET my_index/_search { "query": { "bool": { "must": [ { "match": { "message": "quick" } }, { "match_phrase": { "message": "lazy dog" } } ] } } }
ย
์ ํ๋ - Relevancy
Elasticsearch์ ๊ฐ์ ํ ํ
์คํธ ๊ฒ์์์ง์ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์
๋ ฅ๋ ๊ฒ์ ์กฐ๊ฑด๊ณผ ์ผ๋ง๋ ์ ํํ๊ฒ ์ผ์นํ๋ ์ง๋ฅผ ๊ณ์ฐํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์ง๊ณ ์์ด ์ด ์ ํ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ์๊ฐ ๊ฐ์ฅ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ ๋ณด์ฌ์ค ์ ์์ต๋๋ค. ์ด ์ ํํ ์ ๋๋ฅผ relevancy๋ผ๊ณ ํฉ๋๋ค.
ย
์ค์ฝ์ด(score) ์ ์
๊ฐ ๊ฒ์ ๊ฒฐ๊ณผ์ scoreํญ๋ชฉ์ ์ค์ฝ์ด ์ ์๊ฐ ํ์๋๊ณ ์ด ์ ์๊ฐ ๋์ ๊ฒฐ๊ณผ๋ถํฐ ๋ํ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๋จ์ max_score์๋ ์ ์ฒด ๊ฒฐ๊ณผ ์ค์์ ๊ฐ์ฅ ๋์ ์ ์๊ฐ ํ์๋ฉ๋๋ค. Elasticsearch๋ ์ด ์ ์๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด BM25 ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํฉ๋๋ค.
์ด ๊ณ์ฐ์๋ ํฌ๊ฒ TF, IDF ๊ทธ๋ฆฌ๊ณ Field Length ์ด 3๊ฐ์ง ์์๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
ย
TF (Term Frequency)
๋ํ๋จผํธ ๋ด์ ๊ฒ์๋ ํ
(term)์ด ๋ ๋ง์์๋ก ์ ์๊ฐ ๋์์ง๋ ๊ฒ์ Term Frequency๋ผ๊ณ ํฉ๋๋ค.
ย
IDF (Inverse Document Frequency)
๊ฒ์ํ ํ
์ ํฌํจํ๊ณ ์๋ ๋ํ๋จผํธ ๊ฐ์๊ฐ ๋ง์ ์๋ก ๊ทธ ํ
์ ์์ ์ ์ ์๊ฐ ๊ฐ์ํ๋ ๊ฒ์ Inverse Document Frequency๋ผ๊ณ ํฉ๋๋ค. ๊ฐ๋จํ๊ฒ ์ค๋ช
ํ์๋ฉด ํฌ์ํ ๋จ์ด๊ฐ ๊ฒ์์ ๋ ์ค์ํ ํ
์ผ ๊ฐ๋ฅ์ฑ์ด ๋๋ค๋ ๋ง์
๋๋ค.
ย
Field Length
๋ํ๋จผํธ์์ ํ๋ ๊ธธ์ด๊ฐ ํฐ ํ๋๋ณด๋ค๋ ์งง์ ํ๋์ ์๋ ํ
์ ๋น์ค์ด ๋ ํฝ๋๋ค. ๋ธ๋ก๊ทธ ํฌ์คํธ๋ฅผ ๊ฒ์ํ๋ ๊ฒฝ์ฐ ๊ฒ์ํ๋ ค๋ ๋จ์ด๊ฐ ์ ๋ชฉ๊ณผ ๋ด์ฉ ํ๋์ ๋ชจ๋ ์๋ ๊ฒฝ์ฐ ํ
์คํธ ๊ธธ์ด๊ฐ ๊ธด ๋ด์ฉ ํ๋๋ณด๋ค๋ ํ
์คํธ ๊ธธ์ด๊ฐ ์งง์ ํ๋์ ๊ฒ์์ด๋ฅผ ํฌํจํ๊ณ ์๋ ๋ธ๋ก๊ทธ ํฌ์คํธ๊ฐ ๋ ์ ์๊ฐ ๋๊ฒ ๋ํ๋ฉ๋๋ค.
ย
Bool : Should
bool ์ฟผ๋ฆฌ์ should ๋ ๊ฒ์ ์ ์๋ฅผ ์กฐ์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋์ด์ง๋๋ค.
// fox ๊ฒ์ ๊ฒฐ๊ณผ ์ค lazy๋ฅผ ํฌํจํ ๊ฒฐ๊ณผ์ ๊ฐ์ค์น ๋ถ์ฌ GET my_index/_search { "query": { "bool": { "must": [ { "match": { "message": "fox" } } ], "should": [ { "match": { "message": "lazy" } } ] } } }
// ๊ฒฐ๊ณผ { "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 4, "relation" : "eq" }, "max_score" : 0.9489644, "hits" : [ { "_index" : "my_index", "_type" : "_doc", "_id" : "2", "_score" : 0.9489644, "_source" : { "message" : "The quick brown fox jumps over the lazy dog" } }, { "_index" : "my_index", "_type" : "_doc", "_id" : "1", "_score" : 0.32951736, "_source" : { "message" : "The quick brown fox" } } ] } }
ย
should๋ match_phrase์ ํจ๊ป ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ผํ๋ชฐ ์ํ ๊ฒ์ ๊ฐ์ ์ฌ๋ก์์๋ ๋ณดํต ๊ฒ์์ด๋ก ์
๋ ฅ๋ ๋จ์ด๊ฐ ํ๋๋ผ๋ ํฌํจ๋ ๊ฒฐ๊ณผ๋ค์ ๋ชจ๋ ๊ฐ์ ธ์ค๋๋ก ๋์ด ์์ ๊ฒ์
๋๋ค. ์ด ๋ ๊ฒ์ ๊ฒฐ๊ณผ ์ค์์ ์
๋ ฅํ ๊ฒ์์ด ์ ์ฒด ๋ฌธ์ฅ์ด ์ ํํ ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ฅผ ๋งจ ์์์ ์์น์ํค๋ฉด ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ค์ ๋๋ฝ์ํค์ง ์์ผ๋ฉด์ ์ฌ์ฉ์๊ฐ ์ํ๋ ์์ค ๋์ ํ์ง์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ ์ ์์ ๊ฒ ์
๋๋ค.
ย
์ ํ๊ฐ ์ฟผ๋ฆฌ - Exact Value Query
์ง๊ธ๊น์ง์ ํ ํ
์คํธ ๊ฒ์์ ์ค์ฝ์ด ์ ์ ๊ธฐ๋ฐ์ผ๋ก relevancy๊ฐ ๋์ ๊ฒฐ๊ณผ๋ถํฐ ๊ฐ์ ธ์ต๋๋ค. ์ ํ๊ฐ Exact Value๋ฅผ ํตํด ๊ฐ์ด ์ ํํ ์ผ์นํ๋์ง์ ์ฌ๋ถ๋ฅผ ๋ฐ์ง๋ ๊ฒ์์ด๋ผ๊ณ ์ดํดํ๋ฉด ๋ฉ๋๋ค. Exact Value์๋ term, range ์ ๊ฐ์ ์ฟผ๋ฆฌ๋ค์ด ์ด ๋ถ๋ถ์ ์ํ๋ฉฐ, ์ค์ฝ์ด๋ฅผ ๊ณ์ฐํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ณดํต bool ์ฟผ๋ฆฌ์ filter ๋ด๋ถ์์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
filter ์์ ๋ฃ์ ๊ฒ์ ์กฐ๊ฑด๋ค์ ์ค์ฝ์ด๋ฅผ ๊ณ์ฐํ์ง ์์ง๋ง ์บ์ฑ์ด ๋๊ธฐ ๋๋ฌธ์ ์ฟผ๋ฆฌ๊ฐ ๋ ๊ฐ๋ณ๊ณ ๋น ๋ฅด๊ฒ ์คํ๋ฉ๋๋ค.
bool: filter
GET my_index/_search { "query": { "bool": { "must": [ { "match": { "message": "fox" } } ], "filter": [ { "match": { "message": "quick" } } ] } } }
ย
๊ฒฐ๋ก ์ ์ผ๋ก filter๋ ๊ฒ์์ ์กฐ๊ฑด์ ์ถ๊ฐํ์ง๋ง ์ค์ฝ์ด์๋ ์ํฅ์ ์ฃผ์ง ์๋๋ก ์ ์ดํ ๋ ์ฌ์ฉํฉ๋๋ค. ๋ณดํต ์ผํ๋ชฐ์์ ๊ฒ์์ด๋ก ์ ํ๋๊ฐ ๋์ ์ํ๋ช
์ ๊ฒ์ํ๋ฉด์ ์์ฐ์
์ฒด๋ฅผ ๋ค์ ํํฐ๋ง ํ๋ ๋ฑ์ ์ฉ๋๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
ย
keyword
๋ฌธ์์ด ๋ฐ์ดํฐ๋ keywordํ์์ผ๋ก ์ ์ฅํ์ฌ ์ ํ๊ฐ ๊ฒ์์ด ๊ฐ๋ฅํฉ๋๋ค.
GET my_index/_search { "query": { "bool": { "filter": [ { "match": { "message.keyword": "Brown fox brown dog" } } ] } } }
ย
๋ฒ์ ์ฟผ๋ฆฌ - Range Query
์ซ์, ๋ ์ง ํ์์ range ์ฟผ๋ฆฌ๋ฅผ ์ด์ฉํด ๊ฒ์์ ํฉ๋๋ค.
range ์ฟผ๋ฆฌ๋
range : { <ํ๋๋ช
>: { <ํ๋ผ๋ฉํฐ>:<๊ฐ> } }
์ผ๋ก ์
๋ ฅ๋ฉ๋๋ค. range ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ ์๋์ 4๊ฐ์ง๊ฐ ์์ต๋๋ค. - gte (Greater-than or equal to) - ์ด์ (๊ฐ๊ฑฐ๋ ํผ)
- gt (Greater-than) โ ์ด๊ณผ (ํผ)
- lte (Less-than or equal to) - ์ดํ (๊ฐ๊ฑฐ๋ ์์)
- lt (Less-than) - ๋ฏธ๋ง (์์)
ย
// price ๊ฐ์ด 700 ์ด์ 900 ๋ฏธ๋ง์ธ ๋ฐ์ดํฐ ๊ฒ์ GET phones/_search { "query": { "range": { "price": { "gte": 700, "lt": 900// 700 <= x < 900 } } } }
ย
๋ ์ง ๊ฒ์
// 2016-01-01 ์ดํ์ธ ๋ฐ์ดํฐ ๊ฒ์ GET phones/_search { "query": { "range": { "date": { "gt": "2016-01-01" } } } }
// ๋ ์ง ํฌ๋ฉง์ ๋ค๋ฅด๊ฒ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ format ์ฌ์ฉ GET phones/_search { "query": { "range": { "date": { "gt": "31/12/2015", "lt": "2018", "format": "dd/MM/yyyy||yyyy"// 2015๋ 12์ 31์ผ ๋ถํฐ 2018๋ ์ด์ } } } } // date ๊ฐ์ด 2016-01-01 ์ 6๊ฐ์ ํ ๋ถํฐ ์ค๋ (2019-09-03) ์ 365์ผ ์ด์ ์ฌ์ด ๊ฐ ๊ฒ์ GET phones/_search { "query": { "range": { "date": { "gt": "2016-01-01||+6M", "lt": "now-365d" } } } }
ย
ย
References::
ย
Loading Comments...