【elasticsearch入门】elasticsearch索引的mapping及其设置

mapping 顾名思义,代表了映射关系。是文档中字段和数据类型的映射关系

为什么要了解mapping

虽然elasticsearch中已尽有的动态mapping(Dynamic Mapping),而且新增字段默认也会添加新的mapping,但是毕竟是机器,有时会推算的不对,比如地理位置信息,特殊格式化的日期类型等。这时,如果需要es提供排序、聚合等查询功能,就不能满足我们的需求。

什么是mapping

  • 通过手动设置mapping,我们可以
    • 定义文档里字段的数据类型
    • 定义字段的名称
    • 定义对应字段的是否索引
    • 定义对应字段的分词方式
  • mapping会把JSON文档文档映射成Lucene所需要的扁平格式
  • 一个mapping属于一个索引的type
    • 每个文档都属于一个Type
    • 一个type又一个mapping定义
    • 7.0开始,不需要在mapping定义中指定type信息,因为默认每个索引只有一个type叫"_doc"

查询mapping

#GET 索引名/_mapping
GET mapping_test/_mapping

设置mapping

PUT users
{
    "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text",//text类型全文搜索
          "fields" : {
            "keyword" : {
              "type" : "keyword",//keyword支持聚合查询
              "ignore_above" : 256
            }
          }
        },
        "lastName" : {
          "type" : "keyword",
           "null_value": "NULL"//支持字段为null,只有keyword类型支持
        },
        "mobile" : {
          "type" : "text",
          "index": false//此字段不被索引
        },
        "address":{
            "type":"text",
            "index_options":"offsets"//控制倒排索引记录的内容。offsets最多,记录四个
        }
      }
    }
}

Dynamic Mapping

什么是动态mapping

在写入文档时,如果索引不存在,会自动创建索引,字段类型的自动识别如下:

JSON类型 Elastic search类型
字符串 1、匹配日期格式,设置成Date 2、配置数子设置为float或者long,该选项默认关闭3、设置为text,并且增加keyword字段,超过256位 不分词
布尔值 boolean
浮点数 float
整数 long
对象 object
数组 由第一个非空数值的类型做决定
空值 忽略
PUT dynamic_mapping_test/_mapping
{
  "dynamic": false
}

PUT dynamic_mapping_test/_mapping
{
  "dynamic": strict
}
  • dynamic属性默认为true,新增字段时会自动创建mapping

  • dynamic属性被设置为false时,新增字段不会创建mapping,但是数据会存储,无法根据字段条件查询,但是该字段会会被match_all查询处理

  • dynamic属性被设置为strict时,数据写入直接出错

es中字段对应的数据类型

  • 简单类型
    • text/keyword,对应json中的String,一般会设置字段为text,然后新建个keyword子字段,设置为keyword类型
      • text类型被用来索引长文本,在建立索引前会将这些文本进行分词,转化为词的组合,建立索引。允许es来检索这些词语。text类型不能用来排序和聚合。
      • Keyword类型不需要进行分词,可以被用来检索过滤、排序和聚合。keyword 类型字段只能用本身来进行检索
    • date
    • long, integer, short, byte, double, float
    • boolean
    • IPv4&IPv6
  • 复杂类型-对象和嵌套对象
    • 对象类型/嵌套类型(n)
  • 特殊类型
    • geo_point&geo_shape/percolator

如何设置自定义mapping

常见的属性

  • index 控制当前字段是否被索引,默认为true,如果设置成false,该字段不可被搜索
  • index_options 控制倒排索引记录的内容
    • docs 记录doc id
    • freqs 记录doc id 和term frequencies
    • positions 记录doc id/term frequencies/term position
    • offsets 记录doc id/term frequencies/term position/character offects
  • null_value 需要对字段为null值实现搜索
    • 只有keyword类型支持设定为null_value
  • copy_to
    • _all在7+版本中被copy_t所替代
    • 将字段内容拷贝到目标字段,查询时可以用目标字段作为查询条件,但是不会出现_source中
  • fields
    • 在字段下新增一个字段,可以自定义类型,使用不同的analyzer
    • 可以用来实现以拼音方式搜索中文字段
  • analyzer 分词器
    • standard 默认分词器,按词切分,小写处理
    • simple 按照非字母切分(符号被过滤),小写处理
    • stop 小写处理,停用词过滤(the、a、is)
    • whitespace 按照空格切分,不转小写
    • keyword 不分词,直接将输入当作输出
    • patter 正则表达式,默认\W+(非字符分隔)
    • language 提供了30多种常见语言的分词器(english、german)
    • 中文分词 icu_analyzer、ik、thulac

什么是分词器

分词器分为三部分,分别担任不同的工作

  • character filters 对文本进行预处理,如去除html标签、字符串替换、正则匹配替换
  • tokenizer 将文本按照一定规则,切分为词
  • token filter 将tokenizer切分的词进行增加、修改、删除操作(添加近义词,复数改单数,小写)

设置自定义的分词器

可以将分词器的三个组成部分,自己搭配,实现自定义,也可以用java实现tokenizer插件(我不会)

{
  "tokenizer":"keyword",
  "char_filter":["html_strip"],
  "filter": ["stop","snowball"]
}

{
  "tokenizer":"standard",
  "char_filter": [
      {
        "type" : "mapping",
        "mappings" : [ ":) => happy", ":( => sad"]
      }
    ],
  "filter": ["stop","snowball"]
}

#自定分词器,并且让firstName字段使用自定义分词器
PUT users
{
  "settings": {
      "analysis": {
          "analyzer": {
              "my_custom_analyzer": {
                  "type": "custom",
                  "char_filter": [
                      "emoticons"
                  ],
                  "tokenizer": "punctuation",
                  "filter": [
                      "lowercase",
                      "english_stop"
                  ]
              }
          },
          "tokenizer": {
              "punctuation": {
                  "type": "pattern",
                  "pattern": "[.,!?]"
              }
          },
          "char_filter": {
              "emoticons": {
                  "type": "mapping",
                  "mappings": [
                      ":) => _happy_",
                      ":( => _sad_"
                  ]
              }
          },
          "filter": {
              "english_stop": {
                  "type": "stop",
                  "stopwords": "_english_"
              }
          }
      }
  },
  "mappings" : {
      "properties" : {
        "firstName" : {
          "type" : "text",
          "analyzer": "my_custom_analyzer", 
          "fields": {
            "keyword":{
              "type":"keyword",
              "ignore_above":256
            }
          }
        },
        "lastName" : {
          "type" : "keyword",
           "null_value": "NULL"
        },
        "mobile" : {
          "type" : "text",
          "index": false
        },
        "address":{
            "type":"text",
            "index_options":"offsets"
        }
      }
    }
}

设置索引模版和动态模版

比如索引是日志时,每天增加一个索引,那么设置索引模版可以自动按照模版生成索引mapping,设置分片。

index template

  • 帮助你设定mapping和setting,并按照一定的规则,自动匹配到新创建的索引之上
  • 模版仅在一个索引创建时产生作用,修改模版不会影响已创建的索引
  • 可以设定多个索引模版,这些设置会被“merge”在一起
  • 可以指定“order”的数值,控制“merging”的过程
PUT _template/template_default
{
  "index_patterns": ["*"],
  "order" : 0,
  "version": 1,
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas":1
  }
}


PUT /_template/template_test
{
    "index_patterns" : ["test*"],
    "order" : 1,
    "settings" : {
        "number_of_shards": 1,
        "number_of_replicas" : 2
    },
    "mappings" : {
        "date_detection": false,//匹配字符串转日期功能
        "numeric_detection": true//匹配字符串转数值功能
    }
}

#获取template
GET /_template/temp*

当一个索引被创建时

  1. 应用elasticsearch默认的settings和mappings
  2. 应用order数值低的index template中的设定
  3. 应用order数值高的,之前的设定会被覆盖
  4. 应用创建索引时用户指定的setting和mappings,覆盖之前模版中的设定

dynamic template(感觉用到的不多)

  • 根据elasticsearch识别的数据类型,结合字段名称,对一个索引来动态设定字段类型,比如
    • 所有的字符串类型都设置成keyword
    • is开头的字段都设置成boolean
    • long开头的都设置成long类型
PUT my_index
{
  "mappings": {
    "dynamic_templates": [
            {
        "strings_as_boolean": {
          "match_mapping_type":   "string",
          "match":"is*",
          "mapping": {
            "type": "boolean"
          }
        }
      },
      {
        "strings_as_keywords": {
          "match_mapping_type":   "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容