티스토리 뷰

AWS

elasticsearch nori analyzer index에 적용하기

나를찾는아이 2022. 3. 1. 11:54
728x90
반응형

일단 elasticsearch에 데이터를 생성해봅시다

 

RDB로치자면 테이블이라고 불리는것이 elasticsearch에서는 index라는 이름으로 부릅니다

 

그리고 RDB의 row는 elasticsearch에서는 document라고 부르고요

 

 

game-of-thrones 라는 이름의 인덱스(테이블)에 1개의 도큐먼트(로우)를 넣어볼께요

 

인덱스를 생성하는 작업은 딱히 하지 않고

 

REST API를 호출할때 url에 index이름을 넣어주면 됩니다

 

 

 

POST http://localhost:9200/game-of-thrones/_doc

 

{
    "character": "Ned Stark",
    "quote": "Winter is coming."
}

 

도큐먼트 안에는 character, quote라는 두개의 필드를 넣어볼께요

 

 

{
    "_index": "game-of-thrones",
    "_type": "_doc",
    "_id": "NoVmOX8BL0zcaJp-QX-a",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

 

response를 보니 무사히 도큐먼트가 생성이 되었습니다

 

 

검색쿼리를 통해서 입력한 도큐먼트를 꺼내볼까요

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html

 

Query DSL | Elasticsearch Guide [8.0] | Elastic

Elasticsearch provides a full Query DSL (Domain Specific Language) based on JSON to define queries. Think of the Query DSL as an AST (Abstract Syntax Tree) of queries, consisting of two types of clauses: Leaf query clauses Leaf query clauses look for a par

www.elastic.co

 

 

아직 데이터를 1개밖에 안넣었긴하는데, character라는 필드에 Ned라는 단어가 들어간 도큐먼트를 찾아볼꺼예요

 

 

 

GET http://localhost:9200/game-of-thrones/_search

{
  "query": {
    "match": {
      "character": "Ned"
    }
  }
}

 

결과는 hits 안에 담겨져 리턴됩니다

 

{
    "took": 12,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.2876821,
        "hits": [
            {
                "_index": "game-of-thrones",
                "_type": "_doc",
                "_id": "NoVmOX8BL0zcaJp-QX-a",
                "_score": 0.2876821,
                "_source": {
                    "character": "Ned Stark",
                    "quote": "Winter is coming."
                }
            }
        ]
    }
}

 

입력한 데이터가 잘 나왔네요

 

이렇듯 인덱스(테이블)을 미리 생성하지 않아도 입력한 도큐먼트의 데이터를 토대로 예측해서 자동적으로 생성이 되지만(다이나믹매핑)

 

각 필드가 어떤 타입을 가지고 있는지 어떤 analyzer를 사용해야하는지 지정을 하지 않았기때문에

 

실사용하기에는 부적합합니다

 

 

 

그래서 미리 필드의 타입을 지정하고, analyzer를 설정하여 인덱스를 생성하는것이 좋습니다

 

 

nori analyzer를 elasticsearch의 인덱스에 적용을 해봅시다

analyzer는 text 타입의 필드에 검색시 또는 인덱스될때 사용됩니다

하나의 인덱스에 여러개의 text field가 있다면

각각의 필드에 analyzer를 지정하는 것이 가장 심플하고 명확한 방법이예요



https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html

 

Field data types | Elasticsearch Guide [8.0] | Elastic

Each field has a field data type, or field type. This type indicates the kind of data the field contains, such as strings or boolean values, and its intended use. For example, you can index strings to both text and keyword fields. However, text field value

www.elastic.co

 

엘라스틱서치에는 여러개의 필드타입이 존재하는데요 text 타입일때 analyzer를 통한 fulltext 검색이 가능합니다

 

흔히 text와 keyword 타입의 차이가 뭐지라는 질문이 있는데요

 

text는 풀텍스트 서치가 필요한 텍스트,

keyword는 구조화된 텍스트, 예를들면 ID나 이메일, 우편번호같이 풀텍스트 서치가 필요없는 필드를 지정할때 쓰시면 됩니다

 

 

PUT http://localhost:9200/products

{
    "settings": {
        "analysis": {
            "analyzer": {
                "default": {
                    "type": "nori"
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "price": {
                "type": "double"
            },
            "name": {
                "type": "text",
                "analyzer": "nori"
            },
            "shop_id": {
                "type": "keyword"
            },
            "product_id": {
                "type": "keyword"
            },
            "category_id": {
                "type": "keyword"
            },
            "sex": {
                "type": "keyword"
            },
            "updated_at": {
                "type": "date",
                "format": "epoch_second"
            }
        }
    }
}

 

 

products라고 하는 인덱스를 만들고 그 구조를 미리 세팅합니다

 

name이라고 하는 필드를 text로 지정하고 analyzer를 지정했습니다

 

이 필드에 입력되는 값들이 analyzer를 통하여 색인화됩니다

 

 

{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "products"
}

 

잘 생성되었군요

 

 

    "settings": {
        "analysis": {
            "analyzer": {
                "default": {
                    "type": "nori"
                }
            }
        }
    }

 

제가 인덱스를 생성할때 입력했던 body에서 setting이라는 값에 default라는 값으로 nori analyzer를 지정했는데요

 

이 인덱스에 별다른 analyzer를 지정하지 않았을때 기본적으로 사용되는 analyzer를 지정하는 방법입니다

 

 

이렇게 생성한 인덱스에 도큐먼트를 넣고 다음과 같은 쿼리를 통해서 검색결과를 얻을 수 있습니다

 

 

 

name에 원피스라는 단어가 들어간 도큐먼트 찾기(text 필드)

 

{
    "query": {
        "match": {
            "name": "원피스"
        }
    }
}

 

 

shop_id가 MUSINSA와 일치하는 도큐먼트 찾기(keyword 필드)

 

{
    "query": {
        "term": {
            "shop_id": "MUSINSA"
        }
    }
}

 

 

두개의 and 조건으로 검색하기

 

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "name": "스니커즈"
                    }
                },
                {
                    "term": {
                        "shop_id": "MUSINSA"
                    }
                }
            ]
        }
    }
}

 

가격범위로 검색하기

 

{
    "query": {
        "range": {
            "price": {
                "gte": 15000,
                "lte": 30000
            }
        }
    }
}

 

 

여러개의 필드에서 특정 단어로 검색하기

아래의 예제에 있는 subject, message라는 필드는 제가 위에서 예시로 든 index에는 없는 필드인데요

 

이렇게 검색하면 된다는 예시를 보여드리기 위해 추가로 적었습니다

{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ] 
    }
  }
}

 

 

자 이제 이렇게까지해서

 

인덱스를 생성하고, 해당 인덱스에 저장된 데이터들을 가져오는 방법을 알아보았어요

 

 

당연히

 

도큐먼트를 생성하는 API, 수정하는 API, 삭제하는 API, 인덱스를 수정하는 API 모두 존재하구요

 

관련내용은 공식 문서를 참고하시면 됩니다

 

 

 

 

 

 

 

 

 

 

728x90
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함