elasticsearch 之mapping

原创
2016/12/25 00:23
阅读数 3.5W

elasticsearch 之mapping

前言

在ES中,index相当于数据库,type相当于表,而mapping则相当于表结构。

简单来讲,elasticsearch会在你插入数据的时候,自动根据数据类型设置mapping格式。而且因为一般文档数据都是不规则的,所以ES的mapping会根据插入值格式的变更,自动进行mapping变更。

虽然对于初学者而言,不需要了解mapping里面的各种特性,也可以很方便的使用ES的各种搜索功能,这也是ES推荐的——开箱即用。对初学者来说是十分友好的。

但是对于一个系统开发人员,必须要保证对系统非常熟悉,同时也要对数据的处理进行优化,这就需要进阶学习(如果你还在初级入门阶段,本文章中的内容你可以直接忽略,之后有兴趣再来阅读)。

目录

言归正传,我们分以下几个部分来学习ES的mapping是怎么玩耍的。

  1. mapping说明
  2. mapping的创建及修改方式;
  3. mapping中的可设置的属性;
  4. mapping调优;

mapping说明

ES的mapping非常类似于静态语言中的数据类型:声明一个变量为int类型的变量, 以后这个变量都只能存储int类型的数据。同样的, 一个number类型的mapping字段只能存储number类型的数据。

同语言的数据类型相比,mapping还有一些其他的含义,mapping不仅告诉ES一个field中是什么类型的值, 它还告诉ES如何索引数据以及数据是否能被搜索到。

当你的查询没有返回相应的数据, 你的mapping很有可能有问题。当你拿不准的时候, 直接检查你的mapping。

如何查看当前数据库里面的mapping(你可以用postman或者浏览器访问以下链接):

http://127.0.0.1:9200/{index}/{type}/_mapping?pretty

如果index为: b2bware, type为:commerical_sku

http://127.0.0.1:9200/b2bware/commercial_sku/_mapping?pretty

以上是看某个type下的mapping结构,如果你要看整个库的mapping,URL请去掉type断即可,如:

http://127.0.0.1:9200/b2bware/_mapping?pretty

返回结果如:

{
  "b2bware" : {
    "mappings" : {
      "commercial_sku" : {
        "properties" : {
          "message" : {
            "type" : "string"
          },
          "price" : {
            "type" : "string"
          },
          "tid" : {
            "type" : "string"
          },
          "user" : {
            "type" : "string"
          }
        }
      }
    }
  }
}

mapping的创建及修改方式

mapping的创建

第一种创建方式

就是直接插入数据,然后ES根据插入数据格式自动识别创建mapping,这种傻瓜式的方式非常简便,适合初学者。

如,创建一个ID为1 的新对象: http://127.0.0.1:9200/b2bware/newtable/1

    {
     "name":"test info ",
      "content":"简单的json对象"
    }

第二种创建方式

建index的时候,直接指定mappings,可以一次性创建多个mapping,如下面的代码所示:

URL:

http://127.0.0.1:9200/b2bware

参数body(放在post或者put请求的body部分)

{
  "settings": {
    "index": {
      "number_of_shards": "10",  //分10个片
      "number_of_replicas": "1"  //1个备份
    }
  },
  "mappings": {
    "commercial_sku": { //这是其中一个mapping,你还可以创建其他mapping
      "_timestamp": {  //这个配置可以删掉
        "enabled": true
      },
        "properties": {
          "message": {
            "type": "string"
          },
          "price": {
            "type": "string"
          },
          "tid": {
            "type": "string"
          },
          "user": {
            "type": "string"
          }
        }
    }
  }
}

第三种创建方式

已经创建了index(库已经创建),新增一个mapping

URL:http://127.0.0.1:9200/b2bware/_mapping/article PUT方式

注意,这种创建方式type[表名]是在URL中指定的,BODY部分只是指定了表结构:

{
    "properties": {
      "message": {
        "type": "string"
      },
      "price": {
        "type": "string"
      },
      "tid": {
        "type": "string"
      },
      "user": {
        "type": "string"
      }
    }
}

mapping的修改

因为mapping只能进行追加修改,所以在建type的时候,最好清晰的知道表结构,否则数据变更起来比较麻烦,就像MySQL中已经有一个age存储的是字符串,突然有一天想改为int,因为存在历史数据,要变更就不那么容易。

所以ES的mapping调整只能追加字段,如下,新增一个 visitCount字段:

URL:http://127.0.0.1:9200/b2bware/article/_mapping PUT方式

{
    "properties": {
      "visitCount": {
        "type": "integer"
      }
    }
}

mapping的注意事项

mapping一旦创建之后,就无法修改,只能追加,如果要修改,就需要删除掉整个文档进行重建。

2. mapping中的可设置的属性

mappings : 在index(库)下创建时使用,下面可以有多个mapping 以下数据结构主要针对每个mapping进行说明:

一级属性 二级属性 三级属性 说明
dynamic     新增字段自动模式;true:表示自动识别新字段并创建索引,false:不自动索引新字段,strict:遇到未知字段,抛异常,不能存入
_timestamp     是否使用时间戳,ES会自动加时间戳,使用的话请百度
properties     属性列表(类似数据库多个字段定义)
  {字段名}   某个字段的定义
    type 数据类型,参见数据类型说明
    index 映射选型,参见映射选型说明
    doc_values 布尔值, 对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存
    format 如果数据类型为日期格式,传入值得时候是字符串,ES需要一个格式进行识别,如:yyyy-MM-dd HH:mm: ss
    analyzer 分词器,如ik,ansj(中文分词)
    boost 浮点型,字段级别的分数加权(权重)
    ignore_above 超过多少字符,就不处理,分词性能损耗较大,对字符串较长的可不分词
    null_value 设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词
    store 是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值
    search_analyzer 设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
    其它 similarity,term_vector,norms,include_in_all,index_options,fielddata,ignore_malformed,precision_step

格式错乱请看图片

一个典型的mapping对象的属性有:

{
    "mappings": {
        "my_type": {
        //true:表示自动识别新字段并创建索引,false:不自动索引新字段,strict:遇到未知字段,抛异常,不能存入
            "dynamic":      "strict", 
            
              //动态模板
             "dynamic_templates": [
                    { "stash_template": {
                      "path_match":  "stash.*",
                      "mapping": {
                        "type":           "string",
                        "index":       "not_analyzed"
                      }
                    }}
                  ],
            //属性列表
            "properties": {
                //一个strign类型的字段
                "title":  { "type": "string"},
                
                "stash":  {
                    "type":     "object",
                    "dynamic":  true 
                }
            }
        }
    }
}

Elasticsearch数据类型

Elasticsearch自带的数据类型是Lucene索引的依据,也是我们做手动映射调整到依据。 映射中主要就是针对字段设置类型以及类型相关参数。

JSON基础类型如下:

字符串:string
数字:byte、short、integer、long、float、double、
时间:date
布尔值: true、false
数组: array
对象: object

Elasticsearch独有的类型:

多重: multi
经纬度: geo_point
网络地址: ip
堆叠对象: nested object
二进制: binary
附件: attachment

(3)复合类型

数组类型:没有明显的字段类型设置,任何一个字段的值,都可以被添加0个到多个,要求,他们的类型必须一致: 对象类型:存储类似json具有层级的数据 嵌套类型:支持数组类型的对象Aarray[Object],可层层嵌套

(4)地理类型

geo-point类型: 支持经纬度存储和距离范围检索
geo-shape类型:支持任意图形范围的检索,例如矩形和平面多边形

(5)专用类型 ipv4类型:用来存储IP地址,es内部会转换成long存储
completion类型:使用fst有限状态机来提供suggest前缀查询功能
token_count类型:提供token级别的计数功能
mapper-murmur3类型:安装sudo bin/plugin install mapper-size插件,可支持_size统计_source数据的大小

注意点:

Elasticsearch映射虽然有idnex和type两层关系,但是实际索引时是以index为基础的。 如果同一个index下不同type的字段出现mapping不一致的情况 虽然数据依然可以成功写入并生成并生成各自的mapping, 但实际上fielddata中的索引结果却依然是以index内第一个mapping类型来生成的。

映射选型说明

某个属性(字段)的index可选值有:

analyzed:默认选项,以标准的全文索引方式,分析字符串,完成索引。
not_analyzed:精确索引,不对字符串做分析,直接索引字段数据的精确内容。
no:不索引该字段。

关于动态模板

参考以下链接: https://my.oschina.net/u/204498/blog/529955

展开阅读全文
打赏
3
7 收藏
分享
加载中
supperman博主

引用来自“liyc98”的评论

引用来自“supperman”的评论

引用来自“liyc98”的评论

{
"mappings": {
"my_type": {


//属性列表
"properties": {
//一个strign类型的字段
"title": { "type": "string"},

"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}

如果我要给stash动态添加一个字段,语句应该怎么写
只需要往里面直接写入即可,如下面是一个更新文档ID为100的示例:

http://127.0.0.1:9200/{myindex}/{mytype}/100/_update
上面的100是文档ID

body部分入参:

{
stash:{
"field1":"value1",
"field2":"value2"
}

}

但是我还想手动设置这个字段的类型,分词
上面的文章已经更新,参考:dynamic_templates

也可以看下面这个文章:

https://my.oschina.net/u/204498/blog/529955
2017/06/21 17:24
回复
举报

引用来自“supperman”的评论

引用来自“liyc98”的评论

{
"mappings": {
"my_type": {


//属性列表
"properties": {
//一个strign类型的字段
"title": { "type": "string"},

"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}

如果我要给stash动态添加一个字段,语句应该怎么写
只需要往里面直接写入即可,如下面是一个更新文档ID为100的示例:

http://127.0.0.1:9200/{myindex}/{mytype}/100/_update
上面的100是文档ID

body部分入参:

{
stash:{
"field1":"value1",
"field2":"value2"
}

}

但是我还想手动设置这个字段的类型,分词
2017/06/21 14:47
回复
举报
supperman博主

引用来自“liyc98”的评论

{
"mappings": {
"my_type": {


//属性列表
"properties": {
//一个strign类型的字段
"title": { "type": "string"},

"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}

如果我要给stash动态添加一个字段,语句应该怎么写
只需要往里面直接写入即可,如下面是一个更新文档ID为100的示例:

http://127.0.0.1:9200/{myindex}/{mytype}/100/_update
上面的100是文档ID

body部分入参:

{
stash:{
"field1":"value1",
"field2":"value2"
}

}
2017/06/21 14:08
回复
举报
{
"mappings": {
"my_type": {


//属性列表
"properties": {
//一个strign类型的字段
"title": { "type": "string"},

"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}

如果我要给stash动态添加一个字段,语句应该怎么写
2017/06/20 15:58
回复
举报
更多评论
打赏
4 评论
7 收藏
3
分享
返回顶部
顶部