수색…


비고

index 가 SQL 데이터베이스 인 SQL 데이터베이스의 테이블과 같은 type 쉽게 볼 수 있습니다. 그러나 이것은 type s에 접근하는 좋은 방법이 아닙니다.

모든 유형 정보

사실, 유형은 말 그대로 단지 메타 데이터 필드는 Elasticsearch에 의해 각 문서에 추가됩니다 _type . 위의 예에서는 my_typemy_other_type 두 가지 유형을 만들었습니다. 즉, 유형과 관련된 각 문서에는 "_type": "my_type" 처럼 자동으로 정의되는 추가 필드가 있습니다 "_type": "my_type" ; 이것은 문서로 색인화되어 검색 가능하거나 필터링 가능한 필드 로 만들어 지지만 원시 문서 자체에는 영향을주지 않으므로 응용 프로그램이 걱정할 필요가 없습니다.

모든 유형은 동일한 색인에 존재하므로 색인의 동일한 집단 파편에 있습니다. 디스크 수준에서도 동일한 파일에 있습니다. 두 번째 유형을 만드는 유일한 단점은 논리적 인 것입니다. 고유한지 여부와 관계없이 모든 유형이 맵핑에 존재해야하며 모든 맵핑은 클러스터 상태에 존재해야합니다. 이것은 메모리를 소비하고, 각 유형이 동적으로 갱신되는 경우, 맵핑이 변경 될 때 성능을 저하시킵니다.

따라서 다른 유형이 실제로 필요하지 않는 한 단 하나의 유형 만 정의하는 것이 좋습니다. 여러 유형이 바람직한 시나리오를 보는 것이 일반적입니다. 예를 들어 자동차 색인이 있다고 상상해보십시오. 여러 유형으로 분류하는 것이 유용 할 수 있습니다.

  • BMW
  • 시보레
  • 혼다
  • 마쓰다
  • 메르세데스
  • 닛산
  • 레인저거
  • 도요타
  • ...

이렇게하면 모든 자동차를 검색하거나 주문에 따라 제조업체별로 제한 할 수 있습니다. 두 검색의 차이점은 다음과 같습니다.

GET /cars/_search

GET /cars/bmw/_search

Elasticsearch의 새로운 사용자에게는 분명하지 않은 점은 두 번째 양식이 첫 번째 양식의 전문화라는 점입니다. 문자 그대로 다음과 같이 재 작성됩니다.

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

값이 bmw_type 필드로 인덱싱되지 않은 모든 문서를 단순히 필터링합니다. 모든 문서는 _type 필드로 해당 유형의 색인이 생성되기 때문에 매우 간단한 필터로 사용됩니다. 실제 검색이 두 예제에서 제공된 경우, 필터는 전체 검색에 적절하게 추가됩니다.

따라서 유형이 동일한 경우 단일 유형 (예 :이 예에서는 manufacturer )을 제공하고이를 효과적으로 무시하는 것이 훨씬 좋습니다. 그런 다음 각 문서 내에서 make 또는 원하는 이름을 명시 적으로 제공하고 제한하려는 경우 언제든지 수동으로 필터링하십시오. 이렇게하면 맵핑 크기가 1/n , 여기서 n 은 개별 유형의 수입니다. 다른 방법으로 단순화 된 매핑의 장점으로 각 문서에 다른 필드를 추가합니다.

Elasticsearch 1.x 및 2.x에서 이러한 필드는 다음과 같이 정의해야합니다.

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. 이름은 임의적이다.
  2. 이름은 임의적 이며 원하는 경우 유형 이름과 일치 할 수 있습니다.

Elasticsearch 5.x에서 위의 코드는 여전히 작동하지만 (더 이상 사용되지 않습니다.) 더 나은 방법은 다음을 사용하는 것입니다.

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. 이름은 임의적이다.
  2. 이름은 임의적 이며 원하는 경우 유형 이름과 일치 할 수 있습니다.

인덱스 매핑을 확장하기 때문에 대개 별다른 이점을 얻지 못하므로 형식을 인덱스 내에서 사용하지 않아야합니다. 적어도 하나는 가지고 있어야하지만, 둘 이상을 가져야한다고 말하는 것은 아무것도 없습니다.

일반적인 질문

  • 대부분 두 개 이상의 유형이 있지만 유형마다 고유 한 필드가 몇 개있는 경우 어떻게됩니까?

인덱스 수준에서, 거기에 한 가지 유형의 사이에는 차이가 드문 드문 사용되는 몇 가지 필드 결코 심지어 몇 공유하지 않는 (즉, 다른 유형의 비 스파 스 필드의 무리를 공유하는 여러 종류의 사이에 사용되지되고있는 필드를 사용하여 (에스)).

다르게 말하면 : 유형에 관계없이 색인을 가로 질러 드문 드문 사용되는 필드가 희박 합니다 . 희소성은 별도의 유형으로 정의 되었기 때문에 색인에 도움이되지 않거나 실제로 상처를줍니다.

이러한 유형을 결합하고 별도의 유형 필드를 추가해야합니다.

  • 개별 유형이 필드를 정확하게 정의해야하는 이유는 무엇입니까?

왜냐하면 각 필드는 실제 얼마나 많은 유형이 있는지에 관계없이 Lucene 레벨에서 한 번만 정의되기 때문입니다. 유형이 전혀 존재하지 않는다는 사실은 Elasticsearch의 특징이며 논리적 분리에 불과 합니다.

  • 동일한 필드가 다르게 정의 된 별도의 유형을 정의 할 수 있습니까?

아닙니다. ES 2.x 이상에서 그렇게 할 수있는 방법을 찾으 려면 버그 보고서를 열어야합니다 . 이전 질문에서 언급했듯이 Lucene은이 모든 것을 하나의 필드로 간주하므로이 작업을 적절하게 수행 할 방법이 없습니다.

ES 1.x는 이것을 내재적 요구 사항으로 남겨 두었습니다. 사용자는 인덱스의 한 샤드 매핑이 실제로 같은 인덱스의 다른 샤드와 다른 조건을 만들 수있었습니다. 이것은 효과적으로 경쟁 조건이었고 예기치 않은 문제를 일으킬 수있었습니다 .

규칙 예외

  • 상위 / 하위 문서는 별도의 유형이 동일한 인덱스 내에서 사용할 수 있도록해야합니다.
    • 부모는 한 가지 유형으로 산다.
    • 아이는 별개의 유형으로 살고 있지만 (그러나 각 아이는 부모와 같은 샤드에 있습니다).
  • 엄청난 양의 색인을 생성하는 것이 바람직하지 않으며 스파 스 필드 (sparse fields)의 영향이 대체 방법보다 바람직합니다.
    • 예를 들어 Elasticsearch 모니터링 플러그인 인 Marvel (1.x 및 2.x) 또는 X-Pack Monitoring (5.x +)은 클러스터, 노드, 인덱스, 특정 인덱스 (인덱스 수준)의 변경 사항을 Elasticsearch 자체에서 모니터링합니다. 심지어 파편도. 고유 한 매핑을 가진 문서를 분리하기 위해 매일 5 개 이상의 인덱스를 만들 수 있거나 인덱스를 공유하여 클러스터로드를 줄이는 모범 사례에 위배 될 수 있습니다 (참고 : 정의 된 매핑의 수는 실제로 동일하지만 생성 된 인덱스의 수 n 에서 1로 감소).
    • 이것은 고급 시나리오이지만 여러 유형에서 공유 필드 정의를 고려해야합니다!

유형으로 색인을 명시 적으로 작성

예제에서는 cURL 및 기타 HTTP 응용 프로그램으로 쉽게 변환되는 기본 HTTP를 사용합니다. 또한 Sense 구문과 일치하며 Kibana 5.0에서 Console로 이름이 바뀝니다.

참고 :이 예는 부품에주의를 끌기 위해 <#> 를 삽입합니다. 복사하면 제거해야합니다!

PUT /my_index <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "integer"
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "float"
            }
          }
        }
      }
    }
  },
  "my_other_type": {
    "properties": {
      "field1": {
        "type": "long" <3>
      },
      "field3": { <4>
        "type": "double"
      }
    }
  }
}
  1. 이는 index 작성 엔드 포인트를 사용하여 index 을 작성 중입니다.
  2. 이것은 type 생성합니다.
  3. 동일한 index 내의 type s에있는 공유 필드는 동일한 정의를 공유 해야합니다 ! ES 1.x는이 동작을 엄격하게 시행하지는 않았지만 암묵적인 요구 사항이었습니다. ES 2.x 이상은이 동작을 엄격하게 시행합니다.
  4. type 의 고유 한 필드는 괜찮습니다.

인덱스 (또는 인덱스) 에는 유형이 들어 있습니다. 유형은 문서 분리를위한 편리한 메커니즘이지만 사용하는 각 유형에 대한 매핑을 동적 / 자동 또는 명시 적으로 정의해야합니다. 인덱스에 15 개의 유형을 정의하면 15 개의 고유 맵핑이 있습니다.

이 개념에 대한 자세한 내용과 유형을 사용하려는 이유 또는 사용하지 않는 이유에 대한 설명을 참조하십시오.

유형으로 색인을 동적으로 작성하기

예제에서는 cURL 및 기타 HTTP 응용 프로그램으로 쉽게 변환되는 기본 HTTP를 사용합니다. 또한 Sense 구문과 일치하며 Kibana 5.0에서 Console로 이름이 바뀝니다.

참고 :이 예는 부품에주의를 끌기 위해 <#> 를 삽입합니다. 복사하면 제거해야합니다!

DELETE /my_index <1>

PUT /my_index/my_type/abc123 <2>
{
  "field1" : 1234, <3>
  "field2" : 456,
  "object1" : {
    "field1" : 7.8 <4>
  }
}
  1. 이미 존재하는 경우 (앞의 예 때문에) 색인을 삭제하십시오.
  2. 문서를 색인 my_indexmy_type 유형 및 ID abc123 색인으로 my_index 하십시오 (숫자 일 수도 있지만 항상 문자열 임).
    • 기본적으로 문서를 인덱싱하면 동적 색인을 만들 수 있습니다. 이는 개발 환경에 적합하지만 프로덕션 환경에서는 반드시 좋은 것은 아닙니다.
  3. 이 필드는 정수이므로 처음 표시 될 때 매핑해야합니다. Elasticsearch는 항상 모든 입력 유형에 대해 가장 넓은 유형을 가정하므로 integer 또는 short integer 아닌 long 으로 매핑됩니다 (둘 다 1234456 포함 할 수 있음).
  4. 이 필드에 대해서도 마찬가지입니다. 원하는대로 float 대신 double 로 매핑됩니다.

이 동적으로 생성 된 인덱스 및 유형은 첫 번째 예제에서 정의한 매핑과 대략 일치합니다. 그러나 <3><4> 이 자동으로 정의 된 매핑에 미치는 영향을 이해하는 것이 중요합니다.

동일한 인덱스에 다른 유형을 동적으로 추가하여이를 따를 수 있습니다.

PUT /my_index/my_other_type/abc123 <1>
{
  "field1": 91, <2>
  "field3": 4.567
}
  1. 이 유형은 위의 문서와 유일한 차이점입니다. ID는 동일하고 괜찮습니다! 그것은 다른과는 관계가 없습니다 abc123 이 같은 색인에 일어나는 것을 이외.
  2. field1 이미 색인에 있으므로 다른 유형에 정의 된 것과 동일한 유형의 필드 여야합니다 . 문자열이거나 정수가 아닌 값을 제출하는 것은 실패합니다 (예 : "field1": "this is some text" 또는 "field1": 123.0 ).

이렇게하면 동일한 인덱스 인 my_index 내에서 my_other_type 대한 매핑이 동적으로 생성됩니다.

참고 : Elasticsearch가 색인 시간에 동적으로 색인을 생성하는 대신 매핑을 미리 정의하는 것이 항상 빠릅니다.

두 문서의 색인 생성의 최종 결과는 첫 번째 예제와 유사하지만 필드 유형이 다르기 때문에 약간 낭비합니다.

GET /my_index/_mappings <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "long" <3>
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "double" <4>
            }
          }
        }
      }
    }
  },
  "my_other_type": { <5>
    "properties": {
      "field1": {
        "type": "long"
      },
      "field3": {
        "type": "double"
      }
    }
  }
}
  1. 이것은 _mappings 끝점을 사용하여 우리가 만든 색인에서 매핑을 가져옵니다.
  2. 이 예제의 첫 번째 단계에서는 my_type 을 동적으로 만들었습니다.
  3. field2integer 정의되지 않았으므로 이제 integer 대신 long 입니다. 이 디스크 스토리지의 낭비 인 것을 입증 할 수있다.
  4. object1.field1 은 이제 # 3과 같은 이유로 double 되고 # 3과 동일한 결과를 object1.field1 .
    • 엄밀히 말하자면, 많은 경우에 long 압축 될 수 있습니다. 그러나 double 은 부동 소수점 숫자이기 때문에 압축 할 수 없습니다.
  5. 또한이 예제의 두 번째 단계에서 my_other_type 을 동적으로 만들었습니다. 우리는 이미 longdouble 사용했기 때문에 매핑이 동일하게 발생합니다.
    • field1 my_type 의 정의와 일치 해야 한다는 것을 기억하십시오.
    • field3 은이 유형에 고유하므로 이러한 제한이 없습니다.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow