** 이 자료는 개인 공부용이고, 정답이 아니니 참고하지 않는 것이 더 좋습니다.
select * from "Events" "event" where name like '%네이버%'
name 단일 검색 자체는 괜찮음. -> 100ms 이하
select * from "Events" "event"
inner join "EventMetadata" EM on event."eventId" = EM."eventId"
inner join "Data" D on EM."dataId" = D."dataId" and EM.name = 'contents'
where event.name like '%네이버%'
and D.data like '%네이버%'
이벤트 내용에 대한 질의만 넣으면 -> 400ms 이상
조건 추가하면 1s 까지도 걸릴 수 있었음
인스턴스 자체 성능을 늘려봤을땐 괜찮았지만, 계속된 검색은 견디기 어려워 했음
자연어 검색의 경우, index 또한 무의미했음
ngram 은 Postgres 에서 지원하나, 한글에 적용시키는 것은 너무 어려움
팀원중 하나가 말해서 생각해봤지만, 바로 기각
님이 만들면 쓰겠습니다
GET /production_events
{
"production_events" : {
"aliases" : { },
"mappings" : {
"properties" : {
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
},
마치 DB 의 테이블 느낌 (예전엔 인덱스 이전에 구분가능한게 하나 더 있었는데, 7 버전부터 사라짐)
mapping.properties
각 필드별 맵핑 값들
mapping.properties.${field_name}.type
데이터의 타입, 모든 필드는 따로 맵핑 테이블을 지정하지 않으면, text 타입이 됨
mapping.properties.${field_name}.fields
추가 타입 지정 가능 -> ES 는 이 타입 기준으로 인덱싱을 추가적으로 진행함
문자열이 들어오면, 그 값을 텀 단위로 쪼개놓음 -> 형태소 단위로 쪼개놔서, 단어 기준으로 전문 검색이 가능 / 단 기본설정으로 한글을 제대로 쪼개질 못하고, 네이버
의 네
만 들어와도 검색 안됨.
문자열 전체 값을 저장해놔서, 완전히 모든 문장이 동일하면 검색됨
애널라이저 / 토크나이저를 지정하면 사용할 수 있다. ES 에선 단어를 n 개씩 쪼갬
만약 단어 묶음을 사용하고 싶으면, shingle
이라는 기능을 사용하면 된다.
min_gram
- 최소 단어 수
max_gram
- 최대 단어 수
텍스트가 들어오면 Analyzer
가 받아서, 이 데이터를 분석한다
분석시 어떤 Tokenizer
를 사용할지 설정되어 있어야, 문장 분석을 할 수 있다.
우리는 커스텀 애널라이저에 토크나이저를 ngram 을 사용함
"analysis" : {
"analyzer" : {
"ngram_analyzer" : {
"filter" : [ "lowercase", "trim" ],
"type" : "custom",
"tokenizer" : "ngram_tokenizer"
}
},
"tokenizer" : {
"ngram_tokenizer" : {
"token_chars" : [ "letter", "digit", "punctuation", "symbol" ],
"min_gram" : "1",
"type" : "ngram",
"max_gram" : "5"
}
{
"query": {
"bool": {
"should": [
{
"match": {
"name.keyword": "네이버"
}
},
{
"match": {
"name.ngram": "네이버"
}
},
{
"match": {
"name": "네이버"
}
}
]
}
}
}
should
키워드 안에 넣어버리면, 각 매치된 Score 또한 확인이 가능하며 order 도 스코어 기준으로 가능함. -> 여러 필드 중 가장 높은 값에 매칭되면 그것을 최상단으로
이런식으로 이용하면, 각각의 매치 결과를 적절히 잘 배합해서 보여줄 수 있다.
각각 조건 또한 term
, match
잘 조합해서 보여줄 수 있음
term
순서 상관 없이, 순수하게 토큰만 맞으면 가져옴 -> tag 검색같은거 쓰면 좋을 듯
match
애널라이즈 된 데이터를 기준으로 검색을 함.
~> 순서 상관 없이, 토큰 중 하나라도 일치하면 결과에 포함된다.
match_pharse
match 와 동일하나, 순서도 맞아야함 -> 전문검색에 좋을 듯
일단 당장은 match 만 사용하고, 전문검색은 임시로 제거한 상태