ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 엘라스틱서치 인덱스 매핑
    카테고리 없음 2024. 2. 12. 21:38

    매핑 : 문서가 인덱스에 어떻게 색인되고 저장되는지를 정의

    -> JSON의 각 필드를 어떻게 분석하고 색인할지 어떤 타입으로 저장할지 등을 세부적으로 지정할 수 있음

     

    전 글에서 생성한 인덱스에 문서를 색인한 후 인덱스를 다시 확인해보자

    인덱스에 문서를 색인
    mapping 데이터가 존재

    -> mapping 데이터에 필드의 타입과 관련된 정보가 생성된걸 확인할 수 있음 ( 동적 매핑 )

    -> 기존 mapping 데이터가 존재하지 않으면 엘라스틱서치는 자동으로 적당한 필드 타입을 지정하고 mapping 정보를 생성한다.

    -> PUT 인덱스이름 { "mapping": { "properties": {...}}} 명령을 통해 명시적 매핑이 가능하다.

    -> 매핑 설정 필드 타입은 한번 지정되면 변경이 불가능

    -> 매핑을 어떻게 지정하느냐에 따라 성능차 발생

    필드 타입

    - 심플 타입 : text, keyword, date, long, double, boolean ...

    • 간단한 자료형
    • text, keyword 타입은 매우 중요
    • 부동소수점을 담는 필드라면 환산 계수로 스케일링해서 정수로 저장하는 scaled_float 타입을 고려할 수 있음
      • scaling_factor라는 변수를 지정해야한다.
      • scaling_factor를 100으로 지정하고 값이 1.234라면 엘라스틱서치는 이 값을 123으로 색인한다.
    • date 타입은 epoch miliseconds형식과 format이 적용된 문자열 형식 모두 저장및 검색할 수 있다.
      • 여러 형식을 지원하려면 format을 || 문자로 이어 붙이면 된다.
    • long 타입필드는 숫자 데이터를 넣을 수 있고 숫자로 이뤄진 배열을 넣을 수 있다.
      • 배열 데이터의 타입이 다른 경우 색인은 실패한다.
      • 필드를 query term 으로 검색하는 경우 배열에 속한 숫자와 배열이 아닌 수자 모두를 검색한다.
        • 색인 과정에서 독립적인 역색인을 구성하기 때문에 가능

    배열이 아닐때
    배열일 때

     

    - 계층 구조를 지원하는 타입 : object, nested

    -> object, nested 두 타입은 유사하나 배열을 처리할 때 동작이 다르다.

     

    object 타입

     

    테스트 데이터 삽입 (1)

    PUT object_test/_doc/1
    {
      "price": 3000.55,
      "spec": {
        "name": "엘라스틱서치",
        "content": "엘라스틱 서치 검색 최고",
        "user_score": 4.5
      }
    }

     

    위 object는 내부적으로 아래와 같은 키-값 쌍으로 색인된다.

    {
    "price": 3000.55,
    "spec.name": "엘라스틱서치",
    "spec.content": "엘라스틱 서치 검색 최고",
    "spec.user_score": 4.5
    }

     

    테스트 데이터 삽입 (2)

    PUT object_test/_doc/2
    {
      "spec":[
        {
          "name": "test-name-1",
          "content": "test-content-1",
          "user_score": 4
        },
        {
          "name": "test-name-2",
          "content": "test-content-2",
          "user_score": 1
        },
        {
          "name": "test-name-3",
          "content": "test-content-3",
          "user_score": 5
        }
      ]
    }

     

    위 데이터는 내부적으로 아래처럼 저장된다.

    {
    "spec.name": ["test-name-1", "test-name-2", "test-name-3"],
    "spec.content": ["test-content-1","test-content-2","test-content-3"],
    "spec.user_score": [4, 1, 5]
    }

    -> 위 데이터처럼 저장되기 때문에 name="test-name-1", "content" = "test-content-3"와 같은 조건으로 만족하는 객체는 존재하지 않지만 위 데이터가 검색결과에 잡히게 된다.

    ->object 타입은 배열을 구성하는 객체를 독립적인 데이터로 취급하지 않는다.

     

    nested 타입

     

    먼저 인덱스를 생성할 때 타입을 "nested"라고 지정한다.

    PUT nested_test/_doc/1
    {
      "mappings": {
        "properties": {
          "spec": {
            "type": "nested",
            "properties": {
              "name": {
                "type": "text"
              },
              "content": {
                "type": "text"
              },
              "user_store": {
                "type": "long"
              }
            }
          }
        }
      }
    }

     

    그 후 생성한 인덱스에 데이터를 삽입한다.

    {
      "spec":[
        {
          "name": "test-name-1",
          "content": "test-content-1",
          "user_score": 4
        },
        {
          "name": "test-name-2",
          "content": "test-content-2",
          "user_score": 1
        },
        {
          "name": "test-name-3",
          "content": "test-content-3",
          "user_score": 5
        }
      ]
    }

     

    -> 위 와 같은 테스트 환경을 생성한 후 다시 name= "test-name-1", content=""test-content-2"를 검색하면 검색 결과가 노출되지 않는다.

    -> 하지만 name="test-name-1", content="test-content-1"로 변경하여 검색하면 결과가 나올 것으로 예상하지만 그렇지 않다.

    -> nested 타입은 매우 특수한 타입으로 배열의 부모와 배열의 각 요소를 문서화하여 내부적으로 저장하기 때문에 nested 쿼리를 사용해서 검색해야한다.

    - 내부적으로 객체를 별도의 문서로 분리해서 저장하기 때문에 성능 문제가 발생

    - 인덱스 설정 mapping.nested.fields.limit 옵션 통해 한 인덱스에 nested 타입을 몇 개까지 설정할 수 있는지를 제한할 수 있다.

    - 인덱스 설정 mapping.nested_objects.limit 옵션 통해 한 문서가 nested 객체를 몇 개까지 가질 수 있는지를 제한

     

    nested 쿼리 문법

    GET 인덱스이름/_search
    {
    	"query":{
    		"nested": {
            	"path": "spec" // 검색 필드 이름
                "query": {
                	...
                }
            }
        }
    }

     

     

    - 특수 타입 : geo_point, geo_shape ...

    • geo_point : 위도, 경도를 저장하는 타입
    • geo_shape : 지도상의 특정 지점, 선, 도형 등을 표현하는 타입
    • binary : base64로 인코딩된 문자열을 저장하는 타입
    • completion : 자동완성 검색을 위한 특수 타입
Designed by Tistory.