Elasticsearch-6.x mapping研究

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013501457/article/details/85784162

一. mappings(映射)是什么

es中,有Index(索引),Type(类型,6.x以后一个Index只能拥有一个Type),Document(文档,单行记录),Field(字段,单个文档中的单个字段)这几项组成一条记录。然后,一个Document(文档),包含哪些Field(字段),每个Field(字段)是什么数据类型,采用什么分词机制(例如:中文语句用中文分词机制,英文语句用英文分词机制),这些元数据信息,都是写在mapping中的。

es存在动态映射,即不用预先定义字段,字段类型的mapping信息,当PUT一条记录到es的某个Index的某个Type中时,ES自动分析每个字段的值,配合一些默认设置(例如分词机制,分词最大长度),自动生成出对应的mapping内容。当然,很多时候默认的不会完全符合应用场景,也可能会造成一些不必要的浪费,所以,我们需要研究mapping的组成和功能。

二.mapping怎么查询

//创建空的Index
PUT maptest
{}
//查看mapping信息
GET /maptest/_mapping

显示结果如下:

{
  "maptest": {        //索引名
    "mappings": {}    //mapping信息,没有字段的时候为null,这时候es读取mapping时,使用es默认值。
  }
}

动态映射测试

首先不设置mapping信息,put一条记录到maptest中,es会自动生成对应的mapping信息。

PUT maptest/type/1
{"name":"张三"}

查看动态生成的mapping信息。

{
  "maptest": {                        //索引名
    "mappings": {                     //mappings信息
      "type": {                       //type名 6.0以后一个索引只能有一个type
        "properties": {               //properties存放的是field信息
          "name": {                   //字段name
            "type": "text",           //name的数据类型    [1]
            "fields": {               //multi-fields     [2]
              "keyword": {            //multi-fields 的字段名,keyword
                "type": "keyword",    // keyword的数据类型 keyword
                "ignore_above": 256   // keyword忽略长度  [3]
              }
            }
          }
        }
      }
    }
  }
}

[1]:es支持的数据类型种类 详情参考 ElasticSearch 6.x 学习笔记:12.字段类型

[2]: multi-fields   多域,ES提供的特殊功能,可以让一个字段,同时拥有多个数据类型,原理是存放一个其他数据类型的副本,如上图,name字段是 text类型的,text在es中,存储数据的时候,会自动分词,并生成索引,text无法进行排序,聚合,无法按照精准匹配搜索到结果,keyword支持精准匹配,排序,聚合,但是不支持分词,即关键字检索。所以,mapping自动生成了一个name.keyword多域字段,类型为keyword,这样,name支持分词,name.keyword支持精确匹配,让name同时支持精确匹配和模糊匹配

[3]: keyword类型是将整个文本作为一个词进行匹配,所以当这个词的长度很长时,精确匹配的效率会降低,所以,设置ignore_above长度,超过256字符的keyword文本将无法进行检索(该文本依然会保存,但是无法检索到)。

三. 手动设置mapping

3.1 dynamic-mapping的动态映射参数

mapping的动态映射开关可以设置

POST /maptest/type/_mapping
{
  "maptest": {
    "mappings": {
      "type": {
        "dynamic":"true",                //动态映射开关
        "properties": {
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

在type的下面,可以设置dynamic参数,开关maptest的动态映射。

dynamic属性:

  • dynamic设置为ture:默认值,新增加的字段被添加到索引映射中;
  • dynamic设置为false:新增加的字段会被忽略,字段数据会写入,但是mapping中找不到该字段的properties,并且无法检索;
  • dynamic设置为strict:当向文档中新增字段时,ElasticSearch引擎抛出异常;

下面展示一下false的情况,首先关闭dynamic动态映射,put一个新的字段到mapping中,

//修改mapping dynamic为 false
PUT /maptest/type/_mapping
{
  "type": {
    "dynamic":false
  }
}
// 插入age数据
PUT maptest/type/2
{
  "age":"13"
}
//查询全部数据
GET maptest/_search
{
  "query": {
    "match_all": {}
  }
}

查询结果中,age存在

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "maptest",
        "_type": "type",
        "_id": "2",
        "_score": 1,
        "_source": {
          "age": "13"        // age存在 数据未丢失
        }
      },
      {
        "_index": "maptest",
        "_type": "type",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "张三"
        }
      }
    ]
  }
}

查看mapping,发现age字段没有自动生成映射,无法按age进行数据检索。

{
  "maptest": {
    "mappings": {
      "type": {
        "dynamic": "false",
        "properties": {
          "name": {                    //只有name字段,age字段没有生成mapping
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

如果改成strict模式,然后插入address:"中国"的数据,在查看结果

PUT /maptest/type/_mapping
{
  "type": {
    "dynamic":"strict"
  }
}
// strict模式下,插入mapping中不存在的字段报错,age字段因为已经存在于数据中,没有报错。
PUT maptest/type/3
{
  "address":"中国"
}
{
  "error": {
    "root_cause": [
      {
        "type": "strict_dynamic_mapping_exception",
        "reason": "mapping set to strict, dynamic introduction of [address] within [type] is not allowed"
      }
    ],
    "type": "strict_dynamic_mapping_exception",
    "reason": "mapping set to strict, dynamic introduction of [address] within [type] is not allowed"
  },
  "status": 400
}

3.2 dynamic_date_formats- es date类型识别格式

PUT /maptest/type/_mapping
{
  "type": {
    "dynamic":"true",        // 设置自动映射开始
    "date_detection":true,   // 开启日期转换,默认为true    
    "dynamic_date_formats":["yyyy-MM-dd hh:mm:ss", "yyyy-MM-dd" ] //日期转换的格式
  }
}
// 自动映射
PUT maptest/type/4
{
  "sdate":"2018-11-12"
}

date_detection : 日期检测开关,默认为true,false时关闭

当字段数据为字符串时,如果通过了日期格式检测,则字段类型识别为date类型,默认的日期格式检测为

[ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss || yyyy/MM/dd"]

格式识别可以通过 dynamic_date_formats参数修改

"dynamic_date_formats":["yyyy-MM-dd hh:mm:ss", "yyyy-MM-dd" ]

四.字段属性

这一段可以查阅博客 Elasticsearch整理之mapping的参数,博主对es官方文档进行了详细翻译。

查阅ES官方文档点击这里Mapping parameters

属性名 说明 默认值
analyzer 分词器名称 standard标准分词器
normalizer 统一处理方法,例如将Apple,apple,applE,统一按lowercase处理,检索时全部都能检索到
boost 字段级别的助推,默认值是1,定义了字段在文档中的重要性/权重 1
coerce 尝试将字符串转换为数值,如果字段类型是整数,那么将小数取整 true
copy_to 该属性指定一个字段名称,ElasticSearch引擎将当前字段的值复制到该属性指定的字段中
doc_values 文档值是存储在硬盘上的索引时(indexing time)数据结构,对于index:"not_analyzed"字段,默认值是true,analyzed string字段不支持文档值;  
dynamic 能够动态的增加自动,可对index,单个对象设置 true
enabled 搜索开关,设置为false后,保存数据但是不可检索 true
fielddata 字段数据是存储在内存中的查询时(querying time)数据结构,只支持analyzed string字段  
eager_global_ordinals 按照global ordinals积极把fielddata加载到内存

true

format 指定日期的格式,例如:“yyyy-MM-dd hh:mm:ss”  
ignore_above 该属性值指的是字符数量,而不是字节数量;超过长度后,后面的字符将会被分析器忽略。 256
ignore_malformed 忽略格式错误的数值,默认值是false,不忽略错误格式,对整个文档不处理,并且抛出异常 false
index_options  index_options指出哪些信息被加到倒排索引中,docs,freqs,positions,offsets,stored文档默认为positions,其他文档默认为docs  
index 该属性控制字段是否编入索引被搜索,可以设置为true,false true
fields 多域,一个字段使用多种其他类型的副本数据,满足不同的搜索场景  
norms 用于标准化文档,以便查询时计算文档的相关性。建议不开启 默认不开启 false
null_value 默认情况下值为null的字段不被index和search,该参数可以让值为null的字段变得可index和search  
position_increment_gap 多字段位置相邻度  
properties 嵌套字段,对象的字段信息。  
search_analyzer 搜索时使用的分析器,默认情况下,查询将使用analyzer字段制定的分析器,但也可以被search_analyzer覆盖  
similarity 指定文档的评分模型,参数由"BM25"(默认), "classic"(TF/IDF), "boolean"(布尔评分模型)  
store 指定是否将字段的原始值写入索引,默认值是no,字段值被分析,能够被搜索,但是,字段值不会存储,这意味着,该字段能够被查询,但是不会存储字段的原始值。 no
term_vector 词条向量  

详细解释

4.1 properties-对象类型和嵌套对象属性

ES支持对象数据类型,可以把json识别为嵌套对象,同时,mapping的字段信息中会存在一个properties属性

PUT maptest/type/6
{
  "user":{                //user是一个json对象,es会自动映射
    "id":"123",
    "time":"2018-11-12"
  }
}

mapping的结构如下

{
  "maptest": {
    "mappings": {
      "type": {
        "dynamic": "true",
        "dynamic_date_formats": [
          "yyyy-MM-dd hh:mm:ss",
          "yyyy-MM-dd"
        ],
        "date_detection": true,
        "properties": {            // 第一层properties,type的字段信息
          "user": {                            //user是一个字段
            "properties": {                    //嵌套对象 第二层properties
              "id": {                          //user.id
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "time": {                        //user.time
                "type": "date",
                "format": "yyyy-MM-dd"
              }
            }
          }
        }
      }
    }
  }
}

同时,user.id,user.time是可以检索的

4.2 index-字段检索开关

index: 该属性控制字段是否编入索引被搜索,该属性可以设置为:true,false,默认为true

 

猜你喜欢

转载自blog.csdn.net/u013501457/article/details/85784162