我们如何处理具有特定含义的NULL值?

时间:2016-12-08 11:15:42

标签: elasticsearch null tri-state-logic

问题

我试图将一个布尔值保存到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}

这有几个问题,其中一个是聚合。没有 似乎是获取值truefalseNULL的简单方法 聚合。

我知道missing功能,所以我知道我可以执行以下操作:

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

但这会导致一个包含2个值(真/假)的存储桶和一个单独的存储桶 计算丢失的文件。这看起来会引起问题。

选项2

另一种选择是实际给NULL一个值,如中所述 the manual。问题是价值必须是正确的 类型,并且只有true和false作为布尔值。

  

null_value需要与字段的数据类型相同。   例如,long字段不能包含字符串null_value。

这意味着我们可以使用支持2个以上值的不同类型, 例如整数,但这就像我说的那样:让我们映射 它作为整数,并将1定义为true,将2定义为false,将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" (字符串)当然,但这 是同样的情况,但隐藏得更多。

问题

处理这个null问题的最佳方法是什么? (或者我们应该把它称为“三态布尔问题'?”

澄清一下:我们担心以后会出现非标准的问题。价值可能会导致问题。我们首先看到的是我们可以通过上述脚本解决方案解决的问题,但也许我们稍后会遇到其他问题。因此,我们正在寻找保存此类数据的最佳实践,而不是针对特定问题的快速解决方案。

2 个答案:

答案 0 :(得分:4)

您可以使用terms聚合的missing setting(即不是单独的missing聚合)。

这样,你可以继续使用你的布尔字段并获得你的三个桶0,1和-1(对于null)?

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

它没有缺点,必须更改字段类型并将其编码为其他数据类型(整数/字符串),并且还可以使您免于编写脚本,因为它不能很好地扩展。

答案 1 :(得分:0)

最后我们将各种状态映射到一个字节。

缺失值仅在类型能够具有该值时才有效,因此我们无论如何都需要映射,因此我们在插入期间添加额外的数字。

因此,不是包含truefalsenull值的布尔值,也不是包含12null的整数(如果缺少= -1)值,我们会使用123的字节,意思是(按随机顺序)true,{{1} }和false