ElasticSearch实战--映射(三)

一、映射简介 映射(mapping): 定义index的元数据, 指定要索引并存储的文档的字段类型。也就是说映射决定了Elasticsearch在建立倒排索引、进行检索时对文档采取的相关策略, 如数字类型、日期类型、文本类型等等。
需要注意的是: 检索时用到的分析策略, 要和建立索引时的分析策略相同, 否则将导致数据不准确。
① 比如: 对full text型的数据类型(如text), 在索引时, 会经过各类处理 (包括分词、normalization(时态转换、同义词转换、大小写转换)等处理), 才会建立到索引数据中。
② 再比如: 对exact value(如date), 在索引的分词阶段, 会将整个value作为一个关键词建立到倒排索引中。
Mapping主要类似数据库中表字段定义,主要有如下作用:
定义Index下字段名(Field Name)
定义字段的类型,比如数值型,字符串型、布尔型等
定义倒排索引的相关配置,比如是否索引、记录postion等
需要注意的是,在索引中定义太多字段可能会导致索引膨胀,出现内存不足和难以恢复的情况,下面有几个设置:
index.mapping.total_fields.limit:一个索引中能定义的字段的最大数量,默认是 1000
index.mapping.depth.limit:字段的最大深度,以内部对象的数量来计算,默认是20
index.mapping.nested_fields.limit:索引中嵌套字段的最大数量,默认是50
核心数据类型:
字符串 - text

用于全文索引,该类型的字段将通过分词器进行分词,最终用于构建索引

字符串 - keyword
不分词,只能搜索该字段的完整的值,只用于 filtering

数值型
long:有符号64-bit integer:-2^63 ~ 2^63 - 1 integer:有符号32-bit integer,-2^31 ~ 2^31 - 1 short:有符号16-bit integer,-32768 ~ 32767 byte: 有符号8-bit integer,-128 ~ 127 double:64-bit IEEE 754 浮点数 float:32-bit IEEE 754 浮点数 half_float:16-bit IEEE 754 浮点数 scaled_float

布尔 - boolean
值:false, "false", true, "true"

日期 - date
由于Json没有date类型,所以es通过识别字符串是否符合format定义的格式来判断是否为date类型 format默认为:strict_date_optional_time||epoch_millis format 实测,仅支持"yyyy-MM-dd"、"yyyyMMdd"、"yyyyMMddHHmmss"、"yyyy-MM-ddTHH:mm:ss"、"yyyy-MM-ddTHH:mm:ss.SSS"、"yyyy-MM-ddTHH:mm:ss.SSSZ"格式,不支持常用的"yyyy-MM-dd HH:mm:ss"等格式。注意,"T"和"Z"是固定的字符,在获取"yyyy-MM-ddTHH:mm:ss"、"yyyy-MM-ddTHH:mm:ss.SSS"、"yyyy-MM-ddTHH:mm:ss.SSSZ"格式字符串值时,不能直接以前面格式格式化date,而是需要多次格式化date并且拼接得到

二进制 - binary
该类型的字段把值当做经过 base64 编码的字符串,默认不存储,且不可搜索

二、映射的组成 每个index都有一个type, 每个type对应一个mapping。
在Elasticsearch 6.X版本开始, 1个index只能有1个type。
每个mapping都由下述部分组成:
① 元字段: _index、_type、_id 和 _source.
② field/properties(字段或属性): 同一index中, 同名的field的映射配置必须相同。
因为index是根据_type元字段来区分type的, 也就是存储的每个文档中都有_type等元字段, 如果相同名称的field的映射(_type字段的值)不同, Elasticsearch在解析时就会出现冲突。
元字段
每个文档都有与之关联的元数据 -- ES内部为所有的文档配备的field, 都是以下划线_开头的内置字段。
字段的类型
Elasticsearch中每个field都对应一至多个数据类型。
三、创建mapping
  1. 说明:
    ① 创建mapping时, 可以指定每个field是否需要
索 引: "index": true(默认配置) 不索引: "index": false

② mapping 根对象
每个type对应的mapping的JSON串, 包括properties, metadata(_id, _source, _type) , settings(analyzer) , 其他settings(如include_in_all)。
  1. 创建mapping
    使用mapping创建一个索引。
    索引名:test_index
    类 型:test_type
    字 段:content、id
    指定 content字段使用 english 分析器。
PUT /test_index { "mappings": { "test_type" : { "properties" : { "content" : { "type" :"text", "analyzer": "english" }, "id" : { "type" :"long" } } } } }

结果:
GET /test_index
{ "test_index": { "aliases": {}, "mappings": { "test_type": { "properties": { "content": { "type": "text", "analyzer": "english" }, "id": { "type": "long" } } } }, "settings": { "index": { "creation_date": "1572851323975", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "TJZGsjgcRTa-3iddjV8LRQ", "version": { "created": "6040399" }, "provided_name": "test_index" } } } }

  1. 更新mapping
    (1) 说明:
    映射一旦创建完成, 就不允许修改:
    Elasticsearch对文档的分析、存储、检索等过程, 都是严格按照mapping中的配置进行的. 如果允许后期修改mapping, 在检索时对索引的处理将存在不一致的情况, 导致数据检索行为不准确.
    只能在创建index的时候手动配置mapping, 或者新增field mapping, 但是不能update field mapping
    增加一个新的名为 tag 的不分词的文本字段。
    "index": "false" 为不分词。
PUT /test_index/_mapping/test_type { "properties" : { "tag" : { "type" :"text", "index":"false" } } }

结果:
GET /test_index
{ "test_index": { "aliases": {}, "mappings": { "test_type": { "properties": { "content": { "type": "text", "analyzer": "english" }, "id": { "type": "long" }, "tag": { "type": "text", "index": false } } } }, "settings": { "index": { "creation_date": "1572851323975", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "TJZGsjgcRTa-3iddjV8LRQ", "version": { "created": "6040399" }, "provided_name": "test_index" } } } }

分析:
GET /test_index/_analyze { "field": "content", "text": "Black-cats" }

【ElasticSearch实战--映射(三)】结果:
{ "tokens": [ { "token": "black", "start_offset": 0, "end_offset": 5, "type": "", "position": 0 }, { "token": "cat", "start_offset": 6, "end_offset": 10, "type": "", "position": 1 } ] }

  1. 查看mapping
    GET test_index/_mapping
{ "test_index": { "mappings": { "test_type": { "properties": { "content": { "type": "text", "analyzer": "english" }, "id": { "type": "long" }, "tag": { "type": "text", "index": false } } } } } }

    推荐阅读