풀텍스트 검색을 하기 위해서는 데이터를 검색에 맞게 가공해야함.
ES는 데이터를 저장하는 과정에서 가공작업을 처리.
ES는 데이터를 저장할 때 역 인덱스(Inverted Index) 방식으로 저장
> RDB에서 데이터를 찾을 때
RDB는 테이블 구조로 데이터를 저장하여 텍스트를 찾으려면 한 줄씩 like문을 이용해서 찾음.
-> 데이터가 늘어날 수록 검색해야 할 대상이 늘어 효율성이 떨어짐.
-> Row안의 모든 내용을 읽어야 하기 때문에 기본적으로 속도가 느림
> Elastic Search에서 데이터 저장
각 문장의 단어를 하나하나 쪼개서 단어가 어떤 도큐먼트에 있는지 가리키는 인덱스를 만듦.
추출된 각 키워드를 텀(Term)이라고 부름.
역인덱스가 있으면 해당 단어를 포함하는 도큐먼트의 id를 바로 얻을 수 있음.
텍스트 분석 - Text Analysis
Text Analysis : 텍스트를 term 단위로 쪼개는 과정.
텍스트 분석을 할 때 애널라이저라는 도구를 이용한다.
애널라이저를 이용한 텍스트 분석 과정
1. 캐릭터 필터 : 텍스트 데이터가 입력되면 제일 먼저 거치는 필터로 Pattern Replace, Mapping, HTML Strip 기능을 함.
특정단어를 다른 단어로 바꾸거나, html 문서라면 태그 같은 것 치환을 해줌.
2. 토크나이저 : 주어진 문장을 텀 단위로 쪼개는 과정
3. 토큰 필터 : 쪼개진 각각의 텀들을 가공
- lowercase 토큰 필터 : 대문자를 모두 소문자로 바꿔줌 => 대소문자 구별 없이 검색이 가능.
- stop 토큰 필터 : 검색어로서의 가치가 없는 단어를 제거함. ex) a, an, are, at, be, but, ...etc
- snowball 토큰 필터 : 형태소 분석 과정을 거쳐서 문법상 변형된 단어를 일반적으로 검색에 쓰이는 기본 형태로 변환하여 검색이 가능하게 함. ex) jumps, jumping에 ~s와 ~ing를 제거
- synonym 토큰 필터 : 동의어 지정을 해줄 수 있어서 fast검색했을 때 같은의미인 quick을 포함하는 도큐먼트가 검색되도록 할 수 있음. ex) amazon을 검색해도 AWS를 찾을 수 있게 동의어로 놓음
GET _analyze
{
"text": "The quick brown fox jumps over the lazy dog",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"stop",
"snowball"
]
}
* 토큰 필터를 입력할 때 순서가 중요
: stop 토큰 필터를 lowercase보다 먼저 놓으면 stop 처리시 대문자로 시작하는 The는 불용어로 간주되지 않아 남아있고 그 후에 lowercase가 적용되어서 최종적으로 텀에 the가 역 색인에 남아있게 됨.
애널라이저 사용
1. _analyze API에서 analyzer 항목으로 적용해서 사용이 가능.
2. 캐릭터 필터, 토크나이저, 토큰 필터들을 조합해서 사용자 정의 애널라이저를 만들 수 있음.
3. ES 사전에 정의되어 바로 사용할 수 있는 애널라이저도 있음.
snowball 애널라이저 = whitespace 토크나이저 + lowercase토큰 필터 + stop토큰 필터 + snowball 토큰 필터
따라서 아래의 결과는 위 예제와 같음
GET _analyze
{
"text": "The quick brown fox jumps over the lazy dog",
"analyzer": "snowball"
}
인덱스에서의 사용
인덱스의 매핑 설정에 snowball 애널라이저를 적용하고 "The quick brown fox jumps over the lazy dog" 값을 색인하면 fox, jump, lazi 등의 단어가 검색 텀으로 저장.
match 쿼리로 검색을 수행하면 입력한 검색어도 앞에서 적용한 snowball 애널라이저를 똑같이 거치게 된다.
jumps, jumping등으로 검색을 수행하면 lowercase, snowball 토큰 필터등이 적용되어서 검색어를 jump로 바꾸어 검색.
my_index2라는 인덱스를 생성하는데 필드는 text타입인 message 필드가 있고 여기에 snowball 애널라이저를 적용한다는 의미.
PUT my_index2
{
"mappings": {
"properties": {
"message": {
"type": "text",
"analyzer": "snowball"
}
}
}
}
my_index2에 도큐먼트 저장
PUT my_index2/_doc/1
{
"message": "The quick brown fox jumps over the lazy dog"
}
도큐먼트 검색
여기에 jumps, jump, jumping모두 다 도큐먼트 검색 결과가 나옴.
Y?) 저장할 때 가공과정을 거치기 때문에 감안하는 거라고 생각.
만약 정확하게 message 필드에 입력한 값을 찾고 싶으면 :"match" 대신 "term" 이용
GET my_index2/_search
{
"query": {
"match": {
"message": "jumping"
}
}
}
사용자 정의 애널라이저 생성
"settings" 안에 설정을 해주면 됨.
PUT my_index3
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"stop",
"snowball"
]
}
}
}
}
}
}
사용자 정의 애널라이저 사용
GET my_index3/_analyze
{
"analyzer": "my_custom_analyzer",
"text": [
"The quick brown fox jumps over the lazy dog"
]
}
* 토크나이저와 토큰 필터도 커스텀 생성이 가능
텀들의 정보 확인
GET <인덱스>/_termvectors/<도큐먼트id>?fields=<필드명>
참조
모든 내용은 아래 가이드 북에서 참고해 정리했습니다.
큰 도움 받았습니다. . . .
https://esbook.kimjmin.net/06-text-analysis
'공부' 카테고리의 다른 글
Page로 페이지 처리하기 (0) | 2023.12.10 |
---|---|
Elasticsearch) Mapping (1) | 2023.12.08 |
Elasticsearch) Bool 복합 쿼리 , Should, 정확값 쿼리, 범위 쿼리 (2) | 2023.12.08 |
Elasticsearch) Query DSL (1) | 2023.12.08 |
Elasticsearch) CRUD (1) | 2023.12.08 |