Es索引中时间字段是字符串Range查询的正确姿势

文章目录

    • @[toc]
  • 1. 问题
  • 2. Es索引的mapping模式
    • 2.1 dynamic动态宽松模式(动态映射)
    • 2.2 strict严格模式(静态映射)
  • 3. text类型和keyword类型的区别
    • 3.1 text类型
    • 3.2 keyword类型
  • 4.正确姿势
  • 5. 总结

1. 问题

    由于之前搞了一个使用flink-cdc将mysql表中的数据同步到es的索引中,例子中数据库中的orders表中的order_date的字段类型是datetime类型,flink-sql建表orders、enriched_orders中的order_date 字段是TIMESTAMP(0)类型,同步到es的enriched_orders索引中的order_date的类型是:

查询索引的mapping结构语句:
GET enriched_orders/_mapping
enriched_orders索引的order_date字段类型如下:
"order_date" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
 }

    数据被同步到enriched_orders索引的时候不需要我们创建索引,该索引会自动创建,自动创建的也是可以使用的,如果业务的数据模型有特殊格式要求,可以自己重新设计下数据模型,然后自己先把索引创建好,然后使用cdc同步数据到索引中,需要注意的就是三边的字段的类型的对应,如果字段类型不对应估计是会报错的,这种方式我还没有试过的,哪哈具体的业务上在试下看看,然后就写了下面一个语句根据这个order_date字段查询一个时间范围的数据,DSL语句如下:

GET enriched_orders/_search
{
  "query": {
    "range": {
      "order_date": {
        "gte": "2020-07-30 10:00:00",
        "lte": "2020-07-31 10:38:11"
      }
    }
  }
}

    这种方式居然查不到数据,这也是有点奇葩的,这个问题是分词的问题。

2. Es索引的mapping模式

Elasticsearch 索引映射类型及mapping属性详解

https://www.knowledgedict.com/tutorial/elasticsearch-index-mapping.html

2.1 dynamic动态宽松模式(动态映射)

    Es默认索引的mapping是 dynamic:动态宽松模式,也就是随便写,数据自动冗余,es会根据你写入索引的字段数据进行自动推断该是什么类型,这种方式会导致:字段爆炸(字段膨胀)这种操作在有的时候是很危险的,也就是可以在mapping里面随意加字段,一个不小心随意加了字段可能就导致业务代码报错了,这种方式默认大小为:

index.mapping.total_fields.limit:1000  # dynamic 这种方式最多加到1000字段的限制,想超过1000可以修改这个参数

    可以加上dynamic:"false"的限制,dynamic 设置为 false 后,新来的非 mapping 预设字段数据可以写入,但是:不能被检索,仅支持 Get 获取文档的方式通过 _source 查看详情内容。

2.2 strict严格模式(静态映射)

    也就是当你在写入数据的时候,写入数据格式中的字段不是mapping中定义限定好的,那么将会写入失败,这个就不可以随随便便写入数据了,数据更严谨,一般还是推荐这种方式,先设计数据模型及使用了恰当的类型又使用了更低的存储更切合业务的需求,所以这个还是有必要设计一下的。

3. text类型和keyword类型的区别

3.1 text类型

  1. 会分词,然后进行索引
  2. 支持模糊、精确查询
  3. 不支持聚合
  4. 分词器默认standard ,对于中文来说就是按字分词
  5. 支持fields属性,可以在fields中添加keyword子类型,以实现精确检索

3.2 keyword类型

  1. 不进行分词,直接索引
  2. 支持模糊、精确查询
  3. 支持聚合
  4. 支持按字数建立索引,以便节约索引空间

4.正确姿势

GET enriched_orders/_search
{
  "query": {
    "range": {
      "order_date.keyword": {
        "gte": "2020-07-30 10:00:00",
        "lte": "2020-07-31 10:38:11"
      }
    }
  }
}

GET enriched_orders/_search
{
  "query": {
    "range": {
      "order_date.keyword": {
        "from": "2020-07-30 10:00:00",
        "to": "2020-07-31 10:38:11"
      }
    }
  }
}

    以上的查询语句都是在kibban可视化里执行的:

Es索引中时间字段是字符串Range查询的正确姿势_第1张图片

5. 总结

    到此我的分享就已经结束了,希望能给你带来帮助,请一键三连,么么哒!

你可能感兴趣的:(elasticsearch)