Elasticsearch
지표와 유형의 차이점
수색…
비고
index 가 SQL 데이터베이스 인 SQL 데이터베이스의 테이블과 같은 type 쉽게 볼 수 있습니다. 그러나 이것은 type s에 접근하는 좋은 방법이 아닙니다.
모든 유형 정보
사실, 유형은 말 그대로 단지 메타 데이터 필드는 Elasticsearch에 의해 각 문서에 추가됩니다 _type . 위의 예에서는 my_type 과 my_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"
}
}
}
}
- 이름은 임의적이다.
- 이름은 임의적 이며 원하는 경우 유형 이름과 일치 할 수 있습니다.
Elasticsearch 5.x에서 위의 코드는 여전히 작동하지만 (더 이상 사용되지 않습니다.) 더 나은 방법은 다음을 사용하는 것입니다.
PUT /cars
{
"manufacturer": { <1>
"properties": {
"make": { <2>
"type": "keyword"
}
}
}
}
- 이름은 임의적이다.
- 이름은 임의적 이며 원하는 경우 유형 이름과 일치 할 수 있습니다.
인덱스 매핑을 확장하기 때문에 대개 별다른 이점을 얻지 못하므로 형식을 인덱스 내에서 사용하지 않아야합니다. 적어도 하나는 가지고 있어야하지만, 둘 이상을 가져야한다고 말하는 것은 아무것도 없습니다.
일반적인 질문
- 대부분 두 개 이상의 유형이 있지만 유형마다 고유 한 필드가 몇 개있는 경우 어떻게됩니까?
인덱스 수준에서, 거기에 한 가지 유형의 사이에는 차이가 드문 드문 사용되는 몇 가지 필드 결코 심지어 몇 공유하지 않는 (즉, 다른 유형의 비 스파 스 필드의 무리를 공유하는 여러 종류의 사이에 사용되지되고있는 필드를 사용하여 (에스)).
다르게 말하면 : 유형에 관계없이 색인을 가로 질러 드문 드문 사용되는 필드가 희박 합니다 . 희소성은 별도의 유형으로 정의 되었기 때문에 색인에 도움이되지 않거나 실제로 상처를줍니다.
이러한 유형을 결합하고 별도의 유형 필드를 추가해야합니다.
- 개별 유형이 필드를 정확하게 정의해야하는 이유는 무엇입니까?
왜냐하면 각 필드는 실제 얼마나 많은 유형이 있는지에 관계없이 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로 감소). - 이것은 고급 시나리오이지만 여러 유형에서 공유 필드 정의를 고려해야합니다!
- 예를 들어 Elasticsearch 모니터링 플러그인 인 Marvel (1.x 및 2.x) 또는 X-Pack Monitoring (5.x +)은 클러스터, 노드, 인덱스, 특정 인덱스 (인덱스 수준)의 변경 사항을 Elasticsearch 자체에서 모니터링합니다. 심지어 파편도. 고유 한 매핑을 가진 문서를 분리하기 위해 매일 5 개 이상의 인덱스를 만들 수 있거나 인덱스를 공유하여 클러스터로드를 줄이는 모범 사례에 위배 될 수 있습니다 (참고 : 정의 된 매핑의 수는 실제로 동일하지만 생성 된 인덱스의 수
유형으로 색인을 명시 적으로 작성
예제에서는 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"
}
}
}
}
- 이는
index작성 엔드 포인트를 사용하여index을 작성 중입니다. - 이것은
type생성합니다. - 동일한
index내의types에있는 공유 필드는 동일한 정의를 공유 해야합니다 ! ES 1.x는이 동작을 엄격하게 시행하지는 않았지만 암묵적인 요구 사항이었습니다. ES 2.x 이상은이 동작을 엄격하게 시행합니다. -
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>
}
}
- 이미 존재하는 경우 (앞의 예 때문에) 색인을 삭제하십시오.
- 문서를 색인
my_index에my_type유형 및 IDabc123색인으로my_index하십시오 (숫자 일 수도 있지만 항상 문자열 임).- 기본적으로 문서를 인덱싱하면 동적 색인을 만들 수 있습니다. 이는 개발 환경에 적합하지만 프로덕션 환경에서는 반드시 좋은 것은 아닙니다.
- 이 필드는 정수이므로 처음 표시 될 때 매핑해야합니다. Elasticsearch는 항상 모든 입력 유형에 대해 가장 넓은 유형을 가정하므로
integer또는shortinteger아닌long으로 매핑됩니다 (둘 다1234와456포함 할 수 있음). - 이 필드에 대해서도 마찬가지입니다. 원하는대로
float대신double로 매핑됩니다.
이 동적으로 생성 된 인덱스 및 유형은 첫 번째 예제에서 정의한 매핑과 대략 일치합니다. 그러나 <3> 및 <4> 이 자동으로 정의 된 매핑에 미치는 영향을 이해하는 것이 중요합니다.
동일한 인덱스에 다른 유형을 동적으로 추가하여이를 따를 수 있습니다.
PUT /my_index/my_other_type/abc123 <1>
{
"field1": 91, <2>
"field3": 4.567
}
- 이 유형은 위의 문서와 유일한 차이점입니다. ID는 동일하고 괜찮습니다! 그것은 다른과는 관계가 없습니다
abc123이 같은 색인에 일어나는 것을 이외. -
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"
}
}
}
}
- 이것은
_mappings끝점을 사용하여 우리가 만든 색인에서 매핑을 가져옵니다. - 이 예제의 첫 번째 단계에서는
my_type을 동적으로 만들었습니다. -
field2는integer정의되지 않았으므로 이제integer대신long입니다. 이 디스크 스토리지의 낭비 인 것을 입증 할 수있다. -
object1.field1은 이제 # 3과 같은 이유로double되고 # 3과 동일한 결과를object1.field1.- 엄밀히 말하자면, 많은 경우에
long압축 될 수 있습니다. 그러나double은 부동 소수점 숫자이기 때문에 압축 할 수 없습니다.
- 엄밀히 말하자면, 많은 경우에
- 또한이 예제의 두 번째 단계에서
my_other_type을 동적으로 만들었습니다. 우리는 이미long과double사용했기 때문에 매핑이 동일하게 발생합니다.-
field1은my_type의 정의와 일치 해야 한다는 것을 기억하십시오. -
field3은이 유형에 고유하므로 이러한 제한이 없습니다.
-