(四)elasticsearch之mapping详解和数据类型
程序员文章站
2024-03-02 19:45:16
...
elasticsearch之mapping详解和数据类型
一、mapping介绍
- 类似数据库中的表结构定义,主要作用如下:
- 定义 index 下的字段名(Field name)
- 定义字段的类型,比如 数值型,字符串型,布尔型等
- 定义倒排索引的相关配置,比如是的索引、是否记录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的操作如下:
- 写入一条文档到es 中去,获取es 自动生成的 mapping
- 修改获取的 mapping,按需求自定义相关配置
- 使用修改后的 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
上一篇: Java中字符串拼接的一些细节分析
下一篇: Java读取网页内容并下载图片的实例