第三章 Elasticsearch基础入门知识
前言
这一章,主要介绍ES的Mapping常规设置、数据类型,多字段属性以及分词器一、Mapping常见设置
Mapping可以理解为定义表的结构,字段类型,以及采用何种分词器。
Mapping的主要作用
1、定义字段的名字
2、定义字段的类型
3、定义倒排索引相关的配置(是否被索引、聚合、采用哪种analyzer)
4、Dynamic Mapping有true、false、strict三种设置模式
Mapping 中的字段一旦设定后,禁止直接修改,因为倒排索引生成后不允许直接修改,否则需要重新建立新的索引,通过reindexAPI后期会讲到
#默认Mapping支持dynamic,写入的文档中加入新的字段
PUT dynamic_mapping_test/_doc/1
{
"newField":"someValue"
}
POST dynamic_mapping_test/_search
{
"query":{
"match":{
"newField":"someValue"
}
}
}
#修改为dynamic false
PUT dynamic_mapping_test/_mapping
{
"dynamic":false
}
#新增 anotherField
PUT dynamic_mapping_test/_doc/10
{
"anotherField":"someValue"
}
#该字段不可以被搜索,因为dynamic已经被设置为false
POST dynamic_mapping_test/_search
{
"query":{
"match":{
"anotherField":"someValue"
}
}
}
#查看该索引的mapping,新增的字段没有更新进来
GET dynamic_mapping_test/_mapping
GET dynamic_mapping_test/_search
{
"query": {
"match_all": {}
}
}
#修改为strict
PUT dynamic_mapping_test/_mapping
{
"dynamic": "strict"
}
#写入数据出错,HTTP Code 400
PUT dynamic_mapping_test/_doc/12
{
"lastField":"value"
}
# set mapping‘s’ dynamic to 'true'
PUT dynamic_mapping_test/_mapping
{
"dynamic":true
}
POST dynamic_mapping_test/_doc/13
{
"add_new_field":"add"
}
GET dynamic_mapping_test/_mapping
##
// Dynamic 为false下,无法识别 copy_to字段
GET test3_mapping/_search
{
"query": {
"match": {
"fullName":{
"query": "Zhao Tonghua",
"operator": "and"
}
}
}
}
小结:将Mapping Dynamic设置为"dynamic":true时有新的字段会加入到mapping中(默认true)
将Mapping Dynamic设置为"dynamic":false时,有新的字段加入时不会更新到mapping中,也不会被搜索到,但是会存储在_source,
将Mapping Dynamic设置为"dynamic":strict时,有新的字段加入时,会报错。
二、字段类型
字段类型
1、简单类型
Text/ Keyword
Date
Integer/Floating
Boolean
IPv4 & IPv6
2、复杂类型
对象类型/嵌套类型
3、特殊类型
geo_point & geo_shape / percolator
显示Mapping设置与常见参数
自定义mapping(手动)
技巧:先临时创建一个索引,写入样本数据,然后访问并#复制它的mapping文件,根据自己的需要进行修改,再重新#创建,最后把临时索引删除掉
控制 当前字段是否被索引(要不要索引),是否要聚合,#是否要排序等等
null_value类型,某些字段虽然是空值但是我们依然要搜索
cypy_to设置
数组类型 底层依旧是text类型而不是真的数据类型
代码如下(示例):
DELETE test3_mapping
PUT test3_mapping
{
"mappings": {
// "dynamic": false,
"properties": {
"firstname":{
"type": "text",
"copy_to": "fullName"
},
"lastname":{
"type": "text",
"copy_to": "fullName"
},
"phone":{
"type": "keyword",
"index": false
},
"ID":{
"type": "keyword",
"index": false
},
"introduction":{
"type": "text",
//"analyzer": "ik_smart",
"analyzer": "english"
}
}
}
}
## 数组类型
DELETE users
PUT user/_doc/1
{
"name":"onebobay",
"interests":"reding"
}
PUT user/_doc/2
{
"name":"twobobay",
"interests":["reading","runing","music"]
}
#但是ES底层还是text类型,而不是真正意义上的数组
----------------------
###null_value
DELETE user
PUT users
{
"mappings": {
"properties": {
"firstName":{
"type": "text"
},
"lastNname":{
"type": "text"
},
"mobile":{
"type": "keyword",
"null_value": "NULL"
}
}
}
}
PUT users/_doc/1
{
"firstName":"Ruan",
"lastName": "Yiming",
"mobile": null
}
PUT users/_doc/2
{
"firstName":"Ruan2",
"lastName": "Yiming2",
"mobile":"13596"
}
GET users/_search
{
"query": {
"match": {
"mobile": "NULL"
}
}
}
自定义分词器
可以根据自己的需要自定义分词器,这个也是在ES技术比较有含金量的首先这里我根据阮一鸣教程介绍一下这块知识。
Analysis文本分析
Analysis也叫分词,就是将文本转换成一系列单词的过程,Analysis是通过Analyzer来实现的,ES中有内置的分析器或者还有这里讲的自定义分词器,除了在数据写入时转换词条,匹配Query语句实收也需要用相同的分析器对查询语句进行分析。
Analyzer 分词器
分词器是专门处理分词的组件,Analyzer由三部分组成 Character Filters、Tokenizer、Token Filter。
Character Filters(针对原始文本处理,例如去除himl标签)
Tokenizer 按照规则切分单词比如按照空格等,
Token Filter 将切分的单词进行加工,小写转换,删除stopwords,增加同义词)
#######多字段属性,Mapping中自定义analyzer
#去除html标签
POST _analyze
{
"tokenizer": "keyword",
"char_filter": ["html_strip"],
"text": """"<a id="xl_chrome_ext_download" href="javascript:;" class="xl-chrome-ext-bar__option">下载视频</a>"""
}
//提取邮箱
POST _analyze
{
"tokenizer": "uax_url_email",
"text": ["my emil is 1017921498@qq.com"]
}
//层层路径
POST _analyze
{
"tokenizer": "path_hierarchy",
"text": ["/opt/elastic/conf/elasticsearch.yml"]
}
//标准分词器
POST _analyze
{
"tokenizer": "standard",
"text": ["1017921498@qq.com"]
}
#character filter 进行替换
POST _analyze
{
"tokenizer": "standard",
"char_filter": [
{
"type":"mapping",
"mappings":["- => _"]
}],
"text": "123-456-789! test-990 650-555-1234"
}
# token filter => white space and snowball(例如去除复数、过去现在进行时形式)
GET _analyze
{
"tokenizer": "whitespace",
"filter": ["stop","snowball"],
"text": ["The gilrs in china are playing this game!"]
}
GET _analyze
{
"tokenizer": "whitespace",
"filter": ["lowercase","stop","snowball"],
"text": ["The gilrs in china are playing this game!"]
}
//正则表达式
GET _analyze
{
"tokenizer": "standard",
"char_filter": [
{"type":"pattern_replace",
"pattern":"http://(.*)",
"replacement":"$1"
} ],
// "text":"http://localhost:9200"
"text": ["http://www.elastic.co"]
}
Index Template and Dynamic Template自动化管理索引
代码如下(示例):
#创建一个默认的mapping
PUT ttemplate/_doc/1
{
"someNumber":"1",
"someDate":"2021/03/30"
}
GET template/_mapping
#create a custom template
PUT _template/template_test
{
"index_patterns":["test*"],
"order":1,
"version":1,
"settings":{
//正定分片和副本数量
"number_of_shards":2,
"number_of_replicas":1
},
"mappings":{
//设置是否对日期和数字进行自动识别
"date_detection":false,
"numeric_detection":true
}
}
#put a date
PUT test0330/_doc/1
{
"someNumber":"1",
"someDate":"2021/03/30"
}
GET test0330/_mapping
#cat the template
GET _cat/templates?v
GET test0330/_settings
GET /_template/template_test
GET /_template/temp*
######Dynamic Mapping 作用在具体的索引上
PUT my_index
{
"mappings": {
"dynamic_templates":[
{
"strings_as_boolean":{
"match_mapping_type":"string",
"match":"is*",
"mapping":{
"type":"boolean"
}
}
},
{
"strings_as_keywords":{
"match_mapping_type":"string",
"mapping":{
"type":"keyword"
}
}
}
]
}
}
GET my_index/_mapping
GET my_index/_search
PUT my_index/_doc/1
{
"firstname":"zhao",
"isvip":"true"
}
DELETE my_index
#结合路径
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"full_name":{
"path_match":"name.*",
"path_unmatch":"*.middle",
"mapping":{
"type":"text",
"copy_to":"full_name"
}
}
}
]
}
}
多字段特性
所谓多字段特性,就是为某个字段增加一个子字段,指定它的数据类型或者自定义不同的分词器增加搜索的相关性和返回结果的精准度
总结
这里主要介绍了有关ES Mapping Template有关功能
生产环境下,一般都将Mapping 的dynamic设为false防止mapping字段过度膨胀,template也是非常有用,结合 自定义mapping可以批量自动化管理一类索引,事先规定数据结构和字段、analyzer、alias
数据类型根据业务配合合适的了类型。