(四)elasticsearch之mapping详解和数据类型

elasticsearch之mapping详解和数据类型

一、mapping介绍

  • 类似数据库中的表结构定义,主要作用如下:
  1. 定义 index 下的字段名(Field name)
  2. 定义字段的类型,比如 数值型,字符串型,布尔型等
  3. 定义倒排索引的相关配置,比如是的索引、是否记录position 等

二、常用mapping 相关api

1、获取索引 mapping

请求:GET XXX-INDEX/_mapping
响应:
{
  "test": {
    "mappings": {
      "doc": {
        "properties": {
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

三、自定义mapping

1、dynamic 参数

通过dynamic 参数可以控制字段的新增功能。

  • true(默认)允许自动新增字段
  • false不允许自动新增字段,但是文档可以正常写入,但是无法对字段进行查询等操作
  • strict文档不能写入,插入时会直接报错

如:

1、设置 dynamic 参数
PUT test_index
{
    "mappings": {
        "doc": {
            "dynamic": false,
            "properties": {
                "user": {
                    "type": "text"
                }
            }
        }
    }
}
2、新增一条数据
PUT test_index/doc/1
{
  "user": "qianmeng",
  "age": 18    // 此字段是新增的,此时 dynamic是false,我们验证其可插入但不可查询的功能
}
3、查看mapping
GET test_index/_mapping
结果是:
{
  "test_index": {
    "mappings": {
      "doc": {
        "dynamic": "false",
        "properties": {
          "user": {
            "type": "text"
          }
        }
      }
    }
  }
}
此处第一次证明了dynamic参数的功能(可插入不可查询)
4、查询(试试是否真的不可查询)
GET test_index/_search
{
  "query": {
    "match": {
      "user": "qianmeng"
    }
  }
}

GET test_index/_search
{
  "query": {
    "match": {
      "age": "18"
    }
  }
}
此处再次证明了 dynamic参数的功能,你会发现第一个查询是无法查询出来数据的,请自行验证。strict类似,请自行验证(strict不可插入,比false更加严格);

注:

  • mapping 中的字段类型一旦设定后,禁止直接修改。原因是:Lucene 实现的倒排索引生成后不允许修改。
  • 既然无法修改,或许我们需要重建索引,此时需要做索引数据迁移。es中提供了 reindex 可以帮助我们进行 索引间的数据迁移。
方式一:elasticsearch-migration
	暂不支持join数据类型。
方式二:Logstash
input {
        elasticsearch {
            hosts => ["http://****:9200"]
            index => "*"
            docinfo => true
        }
    }
    output {
        elasticsearch {
            hosts => ["http://****:9200"]
            index => "%{[@metadata][_index]}"
        }
    }
方式三:Snapshot
	前提:需要一个备份仓库。启动时创建,可在elasticsearch.yml中配置开启。path.repo: [/data/backups/elasticsearch”]
方式四:Reindex
	第一步,关闭副本
	PUT mytest/_settings
    {
      "number_of_replicas": 0
    }
    第二步,关闭自动更新
    PUT mytest/_settings
    { "refresh_interval": -1 }
    第三步,迁移数据
   (1)集群内索引间迁移数据 
   POST _reindex?slices=3&wait_for_completion=false
    {
      "source": {
        "index": "applys",	// 源索引
        "size": 3000
      },
      "dest": {
        "index": "twitter"	// 目标索引
      }
    }2)跨集群迁移数据
    POST _reindex?slices=3&wait_for_completion=false
    {
        "source": {
            "remote": {
                "host": "http://****:9200"
            },
            "index": "test1",
            "query": {
                "match": {
                    "title": "elasticsearch"
                }
            }
        },
        "dest": {
            "index": "test2"
        }
    }
注:slices大小=分片数,size大小需要调试(和elasticsearch环境以及索引情况有关);
wait_for_completion=false,此参数的含义是是否等待reindex 操作完成,当数据量较大时,我们无法长时间等待,所以这个参数我一般设置成false,这样他会返回一个 taskid,我们可以根据taskid 查看reidnex 的进程和情况,对应命令是 GET _tasks/xxx-taskid;
此外,记住修改了副本数和刷新设置需要在迁移完成后及时恢复正常设置。

2、copy_to 参数

  • 将该字段的值复制到目标字段,实现类型_all 的作用。
  • 不会出现在 _source中,只用来搜索

例如:


3、index 参数

  • 控制当前字段是否索引,默认为true,即记录索引, false 不记录,即不可搜索
  • 敏感字段常设置成 false,比如身份证,手机号码等
  • 调优可以查看此参数,将只存储不参与搜索的字段设置为 false,性能更好(节省了内存)

例如:

第一步,创建索引,并使用index 参数
PUT my_test
{
  "mappings": {
    "doc": {
      "properties": {
        "first_name": {
          "type": "text",
          "index": false
        },
        "last_name": {
          "type": "text"
        }
      }
    }
  }
}
第二步,插入数据
PUT my_test/doc/1
{
  "first_name": "John",
  "last_name": "Smith"
}
第三步,查询数据
GET my_test/doc/1
// 可以查出数据
GET my_test/_search
{
  "query": {
    "match": {
      "last_name": "Smith"
    }
  }
}
// 不可以查出数据,报错“Cannot search on field [first_name] since it is not indexed”(不可被索引)
GET my_test/_search
{
  "query": {
    "match": {
      "first_name": "John"
    }
  }
}

4、index_options

(1)index_options 用于控制倒排索引的记录内容,有如下4中设置:

  • docs 只记录 doc id
  • freqs 记录doc id 和 term frequencies(词频)
  • positions 记录doc id、term frequencies 和 term position
  • offsets 记录doc id、term frequencies 和 term position和 character offsets

(2)text 类型默认设置是 positions, 其他默认是 docs

(3)记录内容越多,占用空间就越大

例:

PUT my_test
{
  "mappings": {
    "doc": {
      "properties": {
        "first_name": {
          "type": "text",
          "index_options": "positions"
        },
        "last_name": {
          "type": "text"
        }
      }
    }
  }
}

5、null_value

当字段遇到 null 值时的处理策略。默认为null,即空值,此时es 会忽略该值,不保存。可以通过设定该值来设置字段的默认值

例:

PUT my_test
{
  "mappings": {
    "doc": {
      "properties": {
        "first_name": {
          "type": "text"
        },
        "last_name": {
          "type": "keyword",
          "null_value": "haha"
        }
      }
    }
  }
}

四、数据类型

核心数据类型

  • 字符串型:text(会分词)、keyword(不会分词)
  • 数值型:long、integer、short、byte、double、float、half_float、scaled_float
  • 日期类型:date
  • 布尔类型:boolean
  • 二进制类型:binary
  • 范围类型:integer_range、float_range、long_range、double_range、date_range

复杂数据类型

  • 数组类型 array,默认会存储成text
  • 对象类型 object
  • 嵌套类型 nested

地理位置数据类型

  • geo_point
  • geo_shape

专用数据类型

  • 记录ip地址 ip
  • 实现自动补全 completion
  • 记录分词数 token_count
  • 记录字符串hash值:murmur3
  • 父子关系:join

补充:

(1)多字段特性 multi-fields

允许对同一个字段采用不同的配置,比如分词,场景:如对人名实现拼音搜索,只需要在人名中新增一个子字段为 pinyin 即可,如下:

PUT my_test
{
  "mappings": {
    "doc": {
      "properties": {
        "first_name": {
          "type": "text",
          "fields": {
            "pinyin": {					// 新增的子字段
              "type": "text",
              "analyzer": "pinyin"		// 新增的分词器
            }
          }
        },
        "last_name": {
          "type": "keyword"
        }
      }
    }
  }
}
// 查询如下
GET my_test/_search
{
    "query": {
        "match": {
            "first_name.pinyin": "hanhan"		// 子字段的查询
        }
    }
}

五、自动识别字段类型

1、es是 靠 json 文档的字段类型来实现自动识别字段类型,支持的类型如下:

JSON类型 es类型
null 忽视
boolean boolean
浮点类型 float
整数 long
object object
array 由第一个非 null 值的类型决定
string 匹配为日期则设为 date类型;匹配为数字则设为float或long类型;设为text类型,并附带 keyword 的子字段。(从前到后以次匹配)

2、日期的自动识别

  • 日期的自动识别可以自行配置日期格式。
  • 默认是[“strict_date_optional_time”, “yyyy/MM/dd HH:mm:ssZ||yyyy/MM/dd Z”]。
  • dynamic_date_formats 可以自定义日期类型。
  • date_detection 可以关闭日期自动识别的机制,此时保存的是text类型。

3、数字的自动识别

  • 当字符串内容是数字时,默认不会自动识别成整形,因为字符串中出现数字是合理的。
  • numeric_datection 可以开启字符串中数字的自动识别。

六、dynamic templates 动态模板

1、允许根据es 自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果:

  • 所有字符串类型都设定为 keyword 类型,即默认不分词
  • 所有以 message 开头的字段都设定为 text 类型,即默认分词
  • 所有以 long_ 开头的字段都设定为 long 类型
  • 所有自动匹配为 double 类型的都设定为 float 类型,以节省空间

例:

// 匹配 string 类型,并将其改成 keyword 类型
PUT test_index
{
	"mappings": {
    	"docs": {
        	"dynamic_templates": [		// 数组,可指定多个匹配规则
            	{
                	"stringsHanle": {	// template名称,可自定义
                		"match_mapping_type": "string",	// 匹配的规则,此处是匹配字符串类型
                        "mapping": {		// 设置mapping 信息	
                        	"type": "keyword"
                        }
                	}            
            	}
        	]
    	}
	}
}

2、匹配规则

  • match_mapping_type 匹配 es 自动识别的 字段类型,如 boolean、long、string等
  • match,unmatch 匹配字段名
  • path_match,path_unmatch 匹配路径

例:

// 匹配 string 类型,匹配message开头的,并将其改成 keyword 类型
PUT test_index
{
	"mappings": {
    	"docs": {
        	"dynamic_templates": [		// 数组,可指定多个匹配规则
            	{
                	"stringsHanle": {	// template名称,可自定义
                		"match_mapping_type": "string",	// 匹配的规则,此处是匹配字符串类型
                		"match": "message",
                        "mapping": {		// 设置mapping 信息	
                        	"type": "text"
                        }
                	}            
            	}
        	]
    	}
	}
}

七、自定义mapping 的建议(个人)

自定义mapping的操作如下:

  1. 写入一条文档到es 中去,获取es 自动生成的 mapping
  2. 修改获取的 mapping,按需求自定义相关配置
  3. 使用修改后的 mapping 创建实际所需要的索引

八、索引模板

  • index template,主要用于在新建索引 时自动应用预先设定的配置,简化索引创建的操作步骤
  • 可以设置索引的配置和mapping
  • 可以有多个模板,根据order 设置,order 大的覆盖小的配置

例:

PUT _template/test_template					// template 名称
{
    "index_patterns": ["te*", "bar*"],		// 匹配的 索引名称,如te开头
    "order": 0,								// order 顺序设置
    "settings": {
        "number_of_shards": 1
    },
    "mapping": {
        "doc": {
            "properties": {
                "name": {
                    "type": "text"
                }
            }
        }
    }
}

获取与删除索引模板

GET _template
GET _template/xxxx
DELETE _template/xxx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章