1,text
当一个字段的内容需要被全文检索时,可以使用text类型,它支持长内容的存储,如文章内容、商品信息等,该类型的字段在保存时会被分词器分析,并拆分成多个词项,然后根据拆分后的词项生成对应的索引。需要注意的是text类型的字段无法进行精确匹配,也不能直接用于排序、聚合,也被称为ananlyzed字符串。

2,keyword
keyword类型的字段内容不会被分词器分析、拆分,而是根据原始文本直接生成倒排索引,所以keyword类型的字段可以直接通过原始文本精确的检索到。该类型的字段一般用于过滤、排序、聚合操作。

3,日期类型
ES中的date类型黑夜支持如下两种格式:
strict_date_optional_time,表示 yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ 或者 yyyy-MM-dd 格式的日期
epoch_millis,表示从 1970.1.1 零点到现在的毫秒数,
除了指定date类型外,尽量指定相应的格式,如下:

PUT blog{
  "mappings": {
    "properties": {
      "publishDate":{
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}

这里补充下,字段类型如果是date类型,在使用canal同步mysql数据到ES的时候会现出时间格式转换问题。具体如下:

 java.lang.RuntimeException: ES sync commit error ElasticsearchException[Elasticsearch exception 
[type=mapper_parsing_exception, reason=failed to parse field [createTime] of type [date] in document with id 'XXX']]; 
nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Invalid format: "2020-08-25T15:27:01+08:00" is malformed at "-08-25T15:27:01+08:00"]];

很多的解决方案是通过修改canal源码处理的。具体说明可查看canal同步数据到ES时间格式问题
我之前使用ES只是通过时间进行排序,所以我直接将相应的时间字段以long类型即时间戳的格式存储的。在数据同步的时候将数据表里的时间字段转成了时间戳后再进行同步。

4,布尔类型
bolean类型,有true、false两个值

5,数值类型

类型取值范围
byte-2^7 ~ 2^7-1
short-2^15 ~ 2^15-1
integer-2^31 ~ 2^31-1
long-2^63 ~ 2^63-1
float32位单精度IEEE 754浮点类型
double64位双精度IEEE 754浮点类型
half_float16位半精度IEEE 754浮点类型
scaled_float缩放类型的的浮点数

一般情况下,优先使用范围小的类型

6,数组类型
ES里没有专门的数组类型,因为ES中默认每个字段可以包含多个值,只要多个值的类型一致即可。比如有如下索引结构:

PUT index_study
{
    "mappings":{
        "game":{
            "properties":{
                "keyword_id":{
                    "type":"long"
                },
                "keyword_name":{
                    "type":"text",
                    "fields":{
                        "keyword":{
                            "type":"keyword"
                        }
                    }
                }
            }
        }
    }
}

添加两条数据,其中一条中的keyword_name有多个值:

POST index_study/game/1
{
  "keyword_id":1,
  "keyword_name":"青叶"
}
POST index_study/game/2
{
  "keyword_id":2,
  "keyword_name":["山河","曜"]
}

查询后结果如下,GET index_study/_search?q=*

"hits" : [
      {
        "_index" : "index_study",
        "_type" : "game",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "keyword_id" : 2,
          "keyword_name" : [
            "山河",
            "曜"
          ]
        }
      },
      {
        "_index" : "index_study",
        "_type" : "game",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "keyword_id" : 1,
          "keyword_name" : "青叶"
        }
      }
    ]

再聊一下text与keyword类型

我们在使用ES过程中,经常会遇到这样的问题:既要对一下字段进行全文检索,又需要对该字段进行等值查询,如果简单的使用text类型是可以满足全文检索的需求但text是没办法进行等值匹配的。这个时候就需要用到fields来进行配置了
fields的使用场景:

  1. 对一个字段配置我销售点类型的type以应对不同的查询场景
  2. 对一个字段配置多个分词规则以支持多种全文检索规则

索引示例可参看index_study这个索引,在查询的时候使用multi_match进行查询:

GET index_study/_search
{
    "query": {
        "multi_match": {
            "query": "山河",
            "fields": [
                "keyword_name",
                "keyword_name.keyword"
            ],
            "type": "most_fields"
        }
    }
}

参考文章:
es索引字段类型
ES中如何对text字段进行精确匹配


步履不停
38 声望13 粉丝

好走的都是下坡路


« 上一篇
注册中心