2016-12-08 3 views
7

문제특정 의미를 갖는 NULL 값을 어떻게 처리 할 수 ​​있습니까?

내가 elasticsearch하는 부울 값을 저장하기 위해 노력하고있어,하지만 그것이 NULL이 될 위해 특별히 유효 입니다. 이 경우 일종의 신경 쓰지 마라.

몇 가지 옵션이있는 것으로 보이지만, 이 무엇 일지는 완전히 명확하지 않습니다.

우리는 ElasticSearch 버전을 사용하는 5.0.2

옵션 1

사소한 하나가 NULL 값을 부울로 저장하는 것입니다. 그 ES에 의해 '실종'것으로 간주됩니다.

PUT my_index 
{ 
    "mappings": { 
    "my_type": { 
     "properties": { 
     "my_boolean": { "type": "boolean"} 
     } 
    } 
    } 
} 

PUT my_index/my_type/1 
{"my_boolean": true} 

PUT my_index/my_type/2 
{"my_boolean": false} 

PUT my_index/my_type/3 
{"my_boolean": null} 

여기에는 몇 가지 문제가 있습니다. 그 중 하나는 집계입니다. 은 true, falseNULL을 집합으로하는 쉬운 방법 인 것 같습니다.

missing 기능은 나에게 알려진, 그래서 나는 다음 작업을 수행 할 수 있다는 것을 알고있다 :

GET my_index/_search 
{ 
    "size":0, 
    "aggregations": { 
    "my_boolean": { 
     "terms": { 
     "field": "my_boolean" 
     } 
    }, 
    "missing_fields": { 
      "missing" : { 
      "field": "my_boolean" 
      } 
    } 
    } 
} 

그러나 이것은 2 개 값 (참/거짓)과 별도의 카운트 양동이가 발생합니다을 문서가 누락되었습니다. 문제가 생길 것 같습니다.

옵션 2

또 다른 옵션은 the manual에 설명 된대로 실제로 NULL에게 가치를 제공하는 것입니다. 문제는 값이 올바른 유형이어야하고 부울로 true 및 false를 제외한 것입니다.

null_value는 필드와 동일한 데이터 유형이어야합니다. 예를 들어 긴 필드는 null_value 문자열을 가질 수 없습니다.

이것은 우리가 더 다음 2 개 값 예를 지원하는 다른 종류를 사용할 수 있다는 것을 의미 정수,하지만 그건 내 머리 속에 똑같이있다. map 을 정수로 만들고, 1을 참, 2를 거짓, 3을 null로 정의한다. 이 작업은 가능하지만 암시 적 매핑을 사용하면 모두가 을 알아야합니다. (모든 생산자/소비자/whatyamahaveits).

옵션 3

최종 버전은이 문제에서 우리의 방법을 시도하고 스크립트를하는 것입니다.

GET my_index/_search 
{ 
    "size":0, 
    "aggregations": { 

    "my_boolean": { 
     "terms": { 
     "script" : { 
     "inline": "if(doc['my_boolean'].length === 1) { if(doc['my_boolean'].value === true){ return 1;} else {return 2;} } else { return 3;}" 
     } 
     } 
    } 
    } 
} 

이제 우리는 올바른 결과를 얻을 수 있습니다.우리는 여전히 여기에 키 암시 적 매핑이

"aggregations": { 
"my_boolean": { 
    "doc_count_error_upper_bound": 0, 
    "sum_other_doc_count": 0, 
    "buckets": [ 
    { 
     "key": "1", 
     "doc_count": 1 
    }, 
    { 
     "key": "2", 
     "doc_count": 1 
    }, 
    { 
     "key": "3", 
     "doc_count": 1 
    } 
    ] 
} 
} 

참고 그래서 이것은 정수가로 매핑 같은 몇 가지 문제를 갖고있는 것 같아요. 그러나 여전히 데이터 유형이 있어야하므로 일 수 있습니다. 'null'키가있는 버켓을 사용할 수 없습니다. 우리는 "true", "false"및 "null"(문자열)을 호출 할 수 있지만이 은 같은 상황이지만 훨씬 더 숨겨집니다.

질문

이 널 문제를 해결하는 가장 좋은 방법은 무엇입니까? (아니면 우리가 전화를해야 '트라이 상태 부울-문제'?)

명확히하려면 : 우리가 나중에 '비표준'값에 문제가 발생할 수 있음을 우려하고있다. 우리가 본 첫 번째는 위의 스크립트 솔루션으로 해결할 수있는 버킷 팅 이었지만 나중에 다른 문제가 발생할 수 있습니다. 따라서 우리는 특정 문제에 대한 빠른 해결책 대신 이러한 유형의 데이터를 저장하는 최상의 방법을 찾고 있습니다.

+0

좋은 연구. 첫 번째 옵션에서 허/실 버킷 수와 누락 버킷 수는 총 문서 수에 정확하게 합산된다는 것에 동의하십니까? 그렇다면 문제가 발생할 것이라고 생각하는 이유는 무엇입니까? 나는 당신의 문서 수가 증가함에 따라 확장 성이 좋지 않기 때문에 스크립팅에 대해 조언 할 것이다 ... 또 다른 방법은 불린 필드를 깨끗하게 유지할 수 있도록 불린 필드의 3 상태를 다른 필드로 "인코딩"하는 것과 같다. 그 다른 필드를 사용하여 집계를 수행하십시오. – Val

+0

[three-value logic] (https://en.wikipedia.org/wiki/Three-valued_logic)에서 값을 가장 잘 표현하는 방법에 대한 몇 가지 옵션을 검토 한 후에 정수 값을 사용하여 세 가지 상태를 저장하는 것이 일반적입니다 (내 취향 -1/1/1). – Val

+0

또 다른 옵션은'my_boolean' 필드를 두 개의 값 (true/false)을 가진 부울로 유지하고'my_boolean'이'null'이고'null' 인 경우'true'가되는 두 번째 부울 필드'my_null_boolean'을가집니다. my_boolean은 명확한 값을 가진다.'true' 또는'false' 중 하나임 – Val

답변

0

결국 우리는 다양한 상태를 1 바이트로 매핑했습니다.

유형이 해당 값을 가질 수있는 경우에만 누락 값이 작동하므로 매핑이 필요하므로 삽입하는 동안 추가 숫자를 추가합니다.

그래서 대신 true, falsenull 값 또는 1와 정수 2null (누락 = -1) 값 부울, 우리는 임의의 순서로 (1, 23, 의미 바이트를 사용) true, falsenull.

3

terms 집합의 missing setting (즉, missing 집합은 아닙니다)을 사용할 수 있습니다.

그런 식으로 부울 필드를 계속 사용하고 0, 1 및 -1 (null의 경우)으로 버킷 3 개를 얻을 수 있습니까?

{ 
    "size":0, 
    "aggregations": { 
    "my_boolean": { 
     "terms": { 
     "field": "my_boolean", 
     "missing": -1     <--- add this 
     } 
    } 
    } 
} 
그것은 필드 유형을 변경할 필요 및 일부 다른 데이터 형식 (정수/문자열)로 인코딩 단점을 가지고 있고 그것은 아주 잘 확장되지 않기 때문에 또한, 스크립트를 활용에서 당신을 해제하지 않습니다

.