2016-12-08 3 views
7

問題具体的な意味を持つNULL値はどうすれば処理できますか?

私はelasticsearchするブール値を保存しようとしているが、それはNULLであるために、それは 特に有効です。この場合、一種の注意を払わないでください。

は、いくつかのオプションがあるように思えるが、 最善がどうなるか、完全に明確ではありません。

我々はElasticSearchバージョン5.0.2

些細1は、NULL値を持つboolean型として保存することです。オプション1

を使用しています。それらの は、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} 

これにはいくつかの問題があり、そのうちの1つは集計です。そこfalse、値trueを取得する簡単な方法であるように見えると でNULL集約しませ ありません。

missing機能は私に知られているので、私は、私は次の操作を行うことができます知っている:

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

しかし、これは2つの値(真/偽)とに別々の 数でバケツになりますドキュメントがありません。それは問題を引き起こすように見える。 the manualに記載されているように

オプション2

別のオプションは、実際にはNULLに値を与えることです。問題は、値が正しい タイプである必要があり、そして真と偽のbooleanとして何もありません。

null_valueはフィールドと同じデータ型である必要があります。 たとえば、長いフィールドにはnull_valueという文字列を使用できません。

これは、我々は2つの値、 例えば、より多くをサポートしている別のタイプを使用できることを意味します整数が、それは私の頭の中で言って同じようになります:整数としてマップ それをすることができ、そしてヌルとして2偽として、図3に示すように、1のように真を定義します。 これは動作しますが、我々はすべてを約 を知っておくべき暗黙的なマッピングを持っていると思います。 (すべてのプロデューサ/コンシューマ/ whatyamahaveits)。

オプション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

良い研究。あなたの最初の選択肢では、真偽バケツのカウント+欠落バケットのカウントが、合計文書数に正しく加算されることに同意しますか?はいの場合、なぜそれが問題を引き起こすと思いますか?あなたのブール値フィールドがきれいに保つことができるように、あなたのブール値フィールドのトライステートを別のフィールドに "エンコード"することができます他のフィールドを使用して集計を実行します。 – Val

+0

[3値論理](https://en.wikipedia.org/wiki/Three-valued_logic)の値を最もよく表現するためのいくつかのオプションを見直した後、整数値を使用して3つの状態を格納することは珍しくありません私の好みは-1/0/1になる)。 – Val

+0

もう1つの方法は、 'my_boolean'フィールドを2つの値(真/偽)を持つブール値として保持し、' my_boolean'が 'null'で' null'の場合は 'true'になる' my_null_boolean' 'my_boolean'は明確な値を持っています。'true'または' false'のいずれか – Val

答えて

0

最後に、さまざまな状態を1バイトにマッピングしました。

タイプがその値を持つことができる場合にのみ欠損値が機能するため、マッピングが必要なので、挿入時に余分な数値を追加します。

ランダムな順序で

ので、代わりの12nulltruefalsenull値、または整数とブール値(欠落= -1で)、我々は123でバイトを使用し、意味( )true,falseおよびnull

3

termsアグリゲーションのmissing settingを使用することができます(別のmissingアグリゲーションではありません)。

こうすれば、論理フィールドを使い続け、3つのバケットを0,1、-1(nullの場合)にすることができますか?それは非常にうまくスケールしませんので、それは、フィールドタイプを変更することや他のいくつかのデータ型(整数/文字列)にそれをコードしても、スクリプトを活用からあなたを解放するという欠点を持っていない

{ 
    "size":0, 
    "aggregations": { 
    "my_boolean": { 
     "terms": { 
     "field": "my_boolean", 
     "missing": -1     <--- add this 
     } 
    } 
    } 
} 

関連する問題