• mapping 映射


    es的映射就相当于编程语言中给变量定义类型,定义后的变量使用起来更高效,未定义的变量相较于定义的性能肯定是不如的。所以需要掌握es映射。

    未定义映射es会对提供的数据进行类型猜测,如果对自动判断的类型及参数设置不满意,或者需要使用一些更高级的映射设置,那么就需要使用自定义映射。

    添加映射格式:

    curl -XPUT http://localhost:9200/索引名称/类型名称/_mapping?pretty -d '
    {
      "properties":{
        "字段名称":{
          "type":"字段类型",
          "store":"是否存储",
          "index":"索引方式、是否分析"
          ...
        }
      }
    }'
    

    创建my_text3索引

    PUT /my_text3
    {
      "mappings": {
        "doc": {   #类型
          "properties": {
            "name":{   #字段名
              "type": "text"  #字段类型
            }
          }
        }
      }
    }
    

    mapping中字段可查询官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html

    一个索引对应一个映射,一个索引下多个type无法对应多个映射的。7.0版本以后,索引下的type类型就弃用了。最主要原因为了提高性能,具体原因参考官网和此文档链接


    一、字段数据类型:

    • text,keyword,date,long,double,boolean,ip
    • 支持josn的分层特性类型:object,nested
    • 特殊类型: geo_point,geo_shape,completion
      更多类型参考官网文档:链接

    常用类型:

    • text:文本类型,会对内容进行分词,如果不指定分词则使用默认的standard分词器,支持模糊查询。
    • keyword:关键字类型,不会对内容进行分词,只能按其精确值搜索。通常用于过滤、排序和聚合。
    • date:时间类型
    • long,integer:整型
    • double,float:符点数
    • ip :地址类型,搜索时可以位置搜索

    为不同目的以不同方式索引相同字段通常很有用。例如,string可以将字段索引为全文搜索类型text和精确搜索类型keyword,以及用于排序或聚合的字段numeric


    二、索引设置(settings):

    用于控制与索引相关方面配置。如刷新间隔时间,主副分片数等

    PUT /my_text3
    {
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
      }
    }
    
    • number_of_shards :主分片数,默认为5,奇数。7.x版本后默认为1。这里使用单机做实验,只用一个主分片即可
    • number_of_replicas :副本分片,默认为1。当主分片丢失时,可用于数据恢复。这里是单机实验,无所谓副本分片。

    查看索引settings:
    GET /my_text3/_settings?pretty

    更多的setting设置还请参考官网文档
    动态更新setting链接


    三、Meta-fields

    特殊字段,在索引映射中统一以_下划线开头。

    查询结果:

      "hits" : {
        "total" : 1,
        "max_score" : 0.5753642,
        "hits" : [
          {
            "_index" : "my_text3",
            "_type" : "doc",
            "_id" : "3",
            "_score" : 0.5753642,
            "_source" : {
              "name" : "Kobe Bryant",
              "age" : 40
            }
          }
        ]
      }
    }
    

    常见元字段:

    • _id : 唯一标识
    • _index : 索引名,即文档所在的索引
    • _score : 得分
    • _type : 文档的类型名
    • _uid : _type和_id连接一起构造成的复合主键
    • _source : 存储文档中所有字段的集合。默认为true,如果设置为false,那么你将只能指定获取字段搜索和结果。使用默认即可。你也可以尝试设置成false再query下试试。

    默认情况下,_uid字段是被存储(可取回)和索引(可搜索)的。 _type字段被索引但是没有存储,_id_index字段则既没有被索引也没有被存储,这意味着它们并不是真实存在的。_source不被索引被存储。

    更多字段参考官方文档


    四、多重索引

    多重索引只用于textkeyword类型。text字段用于搜索,不可用于排序,聚合等复杂操作。如果非要让text即可搜索也可进行高级操作,带来的代价通常是性能快速下降。所以建议给一个常用的字段定义两种类型,搜索时使用text,高级操作时使用keyword

    PUT /my_text5
    {
      "mappings": {
        "doc": {
          "properties": {
            "name":{
              "type": "text",
              "norms":false,
              "fields": {
                "raw": {      #后缀,会额外生成name.raw的字段,类型为keyword
                  "type":"keyword",
                  "ignore_above":20
                }
              }
            }
          }
        }
      }
    }
    
    ###插入数据
    POST /my_text5/doc/1
    {
      "name":"walter dai"
    }
    
    
    ###查询数据
    GET /my_text5/_search
    {
      "query": {
        "term": {
          "name.raw": "walter dai"    #查询name.raw也可以查询到数据
        }
      }
    }
    
    

    索引中未定义映射的字段,会默认映射成field(text类型)和field.keyword(keyword类型)两种。如果大多数场景用精确查找,可以反过来定义

    "name": {
        "type": "keyword",
        "fields": {
            "text": { "type": "text" }
        }
    }
    

    官方文档


    五、自定义映射

    示例

    PUT /my_text4
    {
      "mappings": {
        "properties": {
          "name":{
            "type": "text",
            "index": true,
            "norms": false, 
            "analyzer": "standard",
            "search_analyzer": "standard"
          },
          "age":{
            "type": "integer"
          },
          "gender":{
            "type": "boolean"
          },
          "country": {
            "type": "keyword",
            "ignore_above": 40
          }
        }
      }
    }
    
    • mappings : 映射
    • doc : _type默认类型。 链接
    • properties :类型映射,object字段和nested字段,并明确定义。默认object
    • name : 索引中的字段名称,下面括号中就是单独给每个字段配置属性
    • type :type设置字段类型,text为字符型,6.x废弃string类型了,integer整形,boolean布尔型true或false,keyword关键字等。链接
    • analyzer,search_analyzer :analyzer存储时的分析器,存储数据时,根据什么分析器来分析数据并倒排索引数据。search_analyzer是搜索时以什么分析器分析搜索数据并去查询匹配相应数据。存储和搜索时的分析器得一致,否则搜索的结果可能不是想要的。
    • index : 区分三种,完全为了性能。
    5.x前 5.x后 意思
    index:analyzed type:text,index:true 分析字符串 ,全文索引。设置为text后,默认为true
    index:not_analyzed type:keyword 精确搜索,不分析
    index:no index:false 不索引,不可被搜索
    • analyzer:插入时分析器,text类型插入时,先分析,在建立倒排索引。
    • search_analyzer :搜索时分析器,搜索时先分析输入数据,并根据评分排序搜索到的数据。

    elastic自带standard,whitesapce,english,simple分析器。如在配置映射时不指定分析器,则默认使用standard分析器。一般analyzer和search_analyzer得一致,不然搜索就可能会得不到想要的结果。中文可使用ik分词器。analyzer详细使用还请参考其它博文

    • ignore_above : 超过的字符将不被索引或存储,限定大小
    • norms : 默认为true,作用是当计算得分时,是否把字段长度用作参数计算。如果此字段仅用于聚合或者过滤,你应该设置为false。以减少磁盘开销

    此处简单列举了些个人常用的配置,详细的配置还请参数官方文档。


    六、动态映射

    在使用之前不需要定义字段和映射类型,适合刚入门elk时使用,索引以logstash-开头就会默认使用动态映射。(程序自带的模版映射)
    动态映射只适用于对数据不了解的情况下使用,否则为了数据的压缩和性能,我们都应该尽量不使用动态映射,除非像nginx request中带有很多个参数,需要将参数抽取出来时,就需要使用动态映射了。请求中的参数过多而无法一一列举出来。

    可动态识别 datebooleanfloatlongobjectarraystring(string分为text和keyword)

    不可以动态识别的类型,如ip:

    PUT /my_text1/doc/10     #试先没有创建,my_text1的映射,直接PUT数据
    {
      "ipp": "192.168.10.3" 
    }
    
    GET /my_text1/_mapping   #查看映射
    {
      "my_text1" : {
        "mappings" : {
          "doc" : { 
            "properties" : {   #默认的双引号内的数据为text和keyword类型
              "ipp" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
    ...
    

    正常情况下,当你自定义映射时,就应该考虑到每个字段的类型,是否需要索引,聚合等一系列后续操作。如果有没法定义的类型数据时,才需要使用dynamic配置项,否则你应该或尽可能给每一个数据类型定义好。

    dynamic支持三种选项:

    • true : 默认值,当有未定义的字段插入时,elastic动态判断类型,无论判断是否成功。都将字段添加到映射中。
    • flase :未定义的字段插入时,将会被忽略,不被索引。但是会存储至_source字段里
    • strict :未定义字段插入时,抛出异常并拒绝文档。

    示例:将所有未定义的字段只映射为keyword类型

    PUT /my_text6
    {
      "mappings": {
        "doc": {
          "dynamic_templates":[    #方括号内是定义动态映射规则
            {
              "message_field":{    #名称
                "match":"*",       #匹配哪些字段,*表示所有未定义的字段。还可以用 match_pattern的正则匹配,glob匹配规则,umatch不匹配某些字段等等
                "mapping":{        #映射成什么类型
                    "type":"keyword",
                    "ignore_above":256
                }
              } 
            }
          ],
          "properties":{    #明确定义字段映射
            "name":{
              "type":"text",
              "norms":false
            }
          }
        }
      }
    }
    

    更多配置参数请参考官网


    七、修改映射

    mapping中已经定义的字段类型,一旦创建,不能修改,不能删除,只可以新增字段。

    PUT /my_text3/doc/_mapping     #使用_mapping接口新增字段映射
    {
      "properties": {
        "age": {       #之前索引中没有的字段
          "type": "integer"
        }
      }
    }
    

    如果需要修改字段映射,则需要使用reindex功能。还请参考另外博文

    八、索引模版

    前面内容中的动态模版是针对字段进行动态匹配。现在有这样一种情况,同一类型的nginx日志,但是存储进es时会有很多索引,这时我们要为每一个索引都先PUT一个映射,然后才能存储数据。这时为了方便同一类型的索引,就可以使用索引模版,定义一个 n-开头的索引名都引用同一个映射。

    模版映射API:

    GET /_cat/templates
    GET /_cat/templates?name=xxx    #查询某个模版
    DELETE /_template/xxx     #删除模版
    

    我的nginx模版:

    curl -XPUT "http://node2003:9200/_template/nginx" -H 'Content-Type: application/json' -d'
    {
      "order": 10,      #优先级,值越大,优先级越高。默认为0
      "index_patterns": "n-*",    #匹配索引的格式,只要匹配上都使用此模版映射
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
      },
      "mappings": {
          "doc":{
          "properties": {
            "@timestamp": {
              "type": "date"
            },
            "agent": {
              "type": "keyword",
              "ignore_above": 256
            },
    		   "city_domain_name":{
    		    	"type":"keyword",
    		    	"ignore_above":256
    	    	},
            "android_version": {
              "type": "keyword"
            },
            "ios_version": {
              "type": "keyword"
            },
            "body_bytes_sent": {
              "type": "integer"
            },
            "http_referer": {
              "type": "text",
              "norms": false,
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "http_x_forwarded_for": {
              "type": "keyword"
            },
            "httpversion": {
              "type": "keyword",
              "index": false
            },
    
            "remote_addr": {
              "type": "ip"
            },
            "request": {
              "type": "text",
              "norms": false,
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "request_body": {
              "type": "text",
              "norms": false
            },
            "request_method": {
              "type": "keyword",
              "ignore_above": 10
            },
            "request_time": {
              "type": "float"
            },
            "scheme": {
              "type": "keyword",
              "ignore_above": 20
            },
            "status": {
              "type": "integer"
            },
            "upstream_addr": {
              "type": "keyword"
            },
            "upstream_cache_status": {
              "type": "keyword"
            },
            "upstream_response_time": {
              "type": "float"
            }	
          }
        }
      }
    }'
    
    
    

    总结:

    mapping映射是非常重要。个人总结如有错误,还望指正。

    官方链接:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html

  • 相关阅读:
    架构设计:负载均衡层设计方案(4)——LVS原理
    架构设计:负载均衡层设计方案(3)——Nginx进阶
    架构设计:负载均衡层设计方案(2)——Nginx安装
    架构设计:负载均衡层设计方案(1)——负载场景和解决方式
    oracle 触发器number判断空值,:NEW赋值,for each row,sql变量引号,to_date,to_char
    oracle触发器调试
    if elsif;报错;new赋值
    求一行的和
    oracle如何获取当年第一月,如今年是2015年,则需获取 201501
    在其他对象上同步
  • 原文地址:https://www.cnblogs.com/dance-walter/p/10684923.html
Copyright © 2020-2023  润新知