欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-02 19:45:16
...

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