Mapping
- 类似数据库中的表结构定义,主要作用如下:
- 定义Index下的字段名(Field Name)
- 定义字段的类型,比如数值型、字符串型、布尔型等
- 定义倒排索引相关的配置,比如是否索引、记录position等。
自定义mapping
- 自定义mapping的api如下所示:
PUT my_index { "mappings":{ "doc":{ "properties":{ "title":{ "type":"text" }, "name":{ "type":"keyword" }, "age":{ "type":"integer" } } } } }
- Mapping中的字段类型一旦设定后,禁止直接修改,原因如下:
- Lucene实现的倒排索引生成后不允许修改
- 重新建立新的索引,然后做reindex操作
- 允许新增字段
- 通过dynamic参数来控制字段的新增
- true(默认)允许自动新增字段
- false不允许自动新增字段,但是文档可以正常写入,但无法对字段进行查询等操作
- strict文档不能写入,报错
copy_to参数
- copy_to
- 将该字段的值复制到目标字段,实现类似_all的作用
- 不会出现在_source中,只用来搜索
PUT my_index { "mappings":{ "doc":{ "properties":{ "first_name":{ "type":""text", "copy_to":"full_name" }, "last_name":{ "type":"text", "copy_to":"full_name" }, "full_name":{ "type":"text" } } } } }
index参数
- index
- 控制当前字段是否索引,默认为true,即记录索引,false不记录,即不可搜索
PUT my_index { "mappings":{ "doc":{ "properties":{ "cookie":{ "type":"text", "index":"false" } } } } }
index_options参数
- 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
- text类型默认配置为positions,其他默认为docs
- 记录内容越多,占用空间越大
- indexoptions设定如下所示:
PUT my_index { "mappings":{ "doc":{ "properties":{ "cookies":{ "type":"text", "index_options":"offsets" } } } } }
- null_value
- 当字段遇到null值时的处理策略,默认为null,即空值,此时es会忽略该值。可以通过设定该值设定字段的默认值
PUT my_index { "mappings":{ "my_type":{ "properties":{ "status_code":{ "type":"keyword", "null_value":"NULL" } } } } }
数据类型
- 核心数据类型
- 字符串:text,keyword
- 数值型:long,integer,short,byte,double,float,half_float,scaled_float
- 布尔:boolean
- 日期:date
- 二进制:binary
- 范围类型:integer_range,float_range,long_range,double_range,date_range
- 复杂数据类型
- 数组类型array
- 对象类型object
- 嵌套类型nested object
- 地理位置数据类型
- geo_point
- geo_shape
- 专用类型
- 记录ip地址ip
- 实现自动补全completion
- 记录分词数token_count
- 记录字符串hash值murmur3
- percolator
- join
- 多字段特性
- 允许对同一个字段采用不同的配置,比如分词,常见例子如对人名实现拼音搜素,只需要在人名中新增一个子字段为pinyin即可
{ "test_index":{ "mappings":{ "doc":{ "properties":{ "username":{ "type":"text", "fields":{ "pinyin":{ "type":"text", "analyzer":"pinyin" } } } } } } } }
Dynamic Mapping
- es可以自动识别文档字段类型,从而降低用户使用成本
- es是依靠json文档的字段类型来实现自动识别字段类型,支持的类型如下:
JSON类型 | es类型 |
null | 忽略 |
Boolean | Boolean |
浮点类型 | float |
整数 | long |
object | object |
array | 有第一个非null值的类型决定 |
string | 匹配为日期则设为date类型(默认开启),匹配为数字的话设为float或long类型(默认关闭),设为text类型,并附带keyword的子字段 |
dynamic日期与数字识别
- 日期的自动识别可以自行配置日期格式,以满足各种需求
- YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-20T15;30:50 +01:00)
- 默认是["strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy /MM/dd Z"]
- strict_date_optional_time是ISO datetime的格式,完整格式类似下面:
- dynamic_date_formats可以自定义日期类型
- date_detection可以关闭日期自动识别的机制
PUT mu_index { "mappings":{ "my_type":{ "dynamic_date_formats":["MM/dd/yyyy"], "date_detection":false } } }
- 字符串是数字时,默认不会自动识别为整型,因为字符串中出现数字是完全合理的
- numeric_detection可以开启字符串中数字的自动识别,如下所示:
PUT my_index { "mappings":{ "my_type":{ "numeric_detection":true } } }
Dynamic Templates
- 允许根据es自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果:
- 所有字符串类型都设定为keyword类型,即默认不分词
- 所有以message开头的字段都设定为text类型,即分词
- 所有以long_开头的字段都设定为long类型
- 所有自动分配为double类型的都设定为float类型,以节省空间
- API如下所示:
PUT test_index { "mappings":{ "doc":{ "dynamic_templates":[#数组,可指定多个匹配规则 { "strings":{ #模板名称 "match_mapping_type":"string",#匹配规则 "mapping":{ "type":"keyword" } } } ] } } }
- 匹配规则一般有如下几个参数:
- match_mapping_type匹配es自动识别的字段类型,如Boolean,long,string等
- match,unmatch匹配字段名
- path_match,path_unmatch匹配路径
自定义mapping的建议
- 自定义Mapping的操作步骤如下:
- 写入一条文档到es的临时索引中,获取es自动生成的mapping
- 修改步骤1得到的mapping,自定义相关配置
- 使用步骤2的mapping创建实际所需索引
首先创建一个文档
PUT my_index/doc/1 { "referrer": "-", "response":"200", "remote_ip":"171.22.12.14", "method":"POST", "user_name":"-", "http_version":"1.1", "body_sent":{ "bytes":"0" }, "url":"/analyzeVideo" }
es会根据创建的文档动态生成映射,可以直接将动态生成的映射直接复制到需要自定义的mapping中
PUT test_index { "mappings": { "doc": { "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "http_version": { "type": "keyword" }, "method": { "type": "keyword" }, "referrer": { "type": "keyword" }, "remote_ip": { "type": "keyword" }, "response": { "type": "long" }, "url": { "type": "text" }, "user_name": { "type": "keyword" } } } } }
这样定义的映射还是比较多余,可以利用动态模板将string类型直接替换成keyword
DELETE test_index PUT test_index { "mappings": { "doc": { "dynamic_templates":[ { "strings":{ "match_mapping_type":"string", "mapping":{ "type":"keyword" } } } ], "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "response": { "type": "long" }, "url": { "type": "text" } } } } }
索引模板
- 索引模板,主要用于在新建索引时自动应用预先设定的配置,简化索引创建的操作步骤
- 可以设定索引的配置和mapping
- 可以有多个模板,根据order设置,order搭的覆盖小的配置
索引模板API如下所示:
PUT _template/test_template { "index_patterns":["te*","bar*"], "order":0, "settings":{ "number_of_shards":1, "number_of_replicas":0 }, "mappings":{ "doc":{ "_source":{ "enabled":false }, "properties":{ "name":{ "type":"keyword" } } } } }
- "index_paterns":匹配的索引名称
- "order":匹配的优先级
- "settings":索引的配置
search API
- 查询有两种形式:
- es提供完备的查询语法Query DSL
- 操作简单,方便通过命令行测试
- 仅包含部分查询语法
- URI search
- Request Body Search
URI Search
- 通过url query参数来实现搜索,常用参数如下:
- q 指定查询的语句,语法为Query String Syntax
- df q中不指定字段时默认查询的字段,如果不指定es会查询所有字段
- sort 排序
- timeout 指定超时时间,默认不超时
- from,size用于分页
URI Search - Query String Syntax
- term与phrase
- alfred way 等效于Alfred OR way
- "alfred way" 词语查询,要求先后顺序
- 泛查询
- alfred 等效于在所有字段去匹配该term
- 指定字段
- name:alfred
- Group分组设定,使用括号指定匹配的规则
- (quick OR brown) AND fox
- status:(active OR pending) title:(full text search)
- 布尔操作符
- name:(tom NOT lee)
- 注意大写,不能小写
- AND(&&),OR(||),NOT(!)
- +—分别对应must和must_not
- name:(tom +lee -alfred) #返回一定包含lee,可以包含tom,一定不包含alfred的文档
- name:((lee && !alfred)) || (tom && lee && !alfred)
- +在url中会被解析为空格,要使用encode后的结果才可以,为%2B
- 范围查询,支持数值和日期
- age:>=1
- age:(>=1 && <=10) 或者age:(+>=1 +<=10)
- age:[1 TO 10] 意为1<=age<=10
- age:[1 TO 10} 意为1<=age<10
- age:[1 TO] 意为age>=1
- age:[* TO 10] 意为age<=10
- 区间写法,闭区间用[],开区间用{}
- 算数符号写法
- 通配符查询
- name:t?m
- name:tom*
- name:t*m
- 通配符匹配执行效率低,且占用较多内存,不建议使用
- 如无特殊需求,不要将?/*放在最前面
- ?代表1个字符,*代表0或多个字符
- 正则表达式匹配
- name:/[mb]oat/
- 模糊匹配fuzzy query
- name:roam~1
- 匹配与roam差一个character的词,比如foam roams等
- 近似度查询 proximity search
- "fox quick" ~5
- 以term为单位进行差异比较,比如"quick fox" "quick brown fox"都会被匹配
Query DSL
- 基于json定义的查询语句,主要包含如下两种类型:
- 如bool查询等,包含一个或多个字段类查询或者复合查询语句
- 如term,match,range等,只针对某一个字段进行查询
- 字段类查询:
- 复合查询
Query DSL 字段类查询
- 字段类查询主要包括以下两类:
- 不会对查询语句做分词处理,直接去匹配字段的倒排索引,如term.terms,range等query类型
- 针对text 类型的字段进行全文检索,会对查询语言先进行分词处理,如match,match_phrase等query类型
- 全文匹配
- 单词匹配
Match Query
- 对字段作全文检索,最基本和常用的查询类型,API示例如下:
GET test_index/_search { "query":{ "match":{ #关键词 "remote_ip":"171.22.12.14" #字段名 } } }
响应结果如下:
{ "took": 4, #查询总用时 "timed_out": false, #是否超时 "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, #匹配文档总数 "max_score": 0.2876821, "hits": [ #返回文档列表 { "_index": "test_index_index", "_type": "doc", "_id": "1", "_score": 0.2876821, #文档相关度得分 "_source": { #文档原始内容 "referrer": "-", "response": "200", "remote_ip": "171.22.12.14", "method": "POST", "user_name": "-", "http_version": "1.1", "body_sent": { "bytes": "0" }, "url": "/analyzeVideo" } } ] } }
- 通过operator参数可以控制单词间的匹配关系,可选项为or和and
- 通过minimum_should_match参数可以控制需要匹配的单词数
Match Query -流程
首先对查询语句进行分词,分词后分别根据字段的倒排索引进行匹配算分,并会匹配到一个或多个文档,再将匹配到的文档进行汇总得分,根据得分排序返回多个文档
Match Phrase Query
- 对字段做检索,有顺序要求,API示例如下:
GET test_index_index/_search { "query":{ "match_phrase":{ "remote_ip":"171.22.12.14" } } }
- 通过slop参数可以控制单词间的间隔
Query String Query
- 类似于URI Search中的q参数查询
GET test_index_index/_search { "query":{ "query_string":{ "default_field":"remote_ip", "query":"171.22.12.14" } } }
Simple Query String Query
- 类似Query String,但是会忽略错误的查询语法,并且仅支持部分查询语法
- 其常用的逻辑符号如下,不能使用AND、OR、NOT等关键词:
- +代指AND
- |代指OR
- -代指NOT 常用API如下所示:
GET test_index_index/_search { "query":{ "simple_query_string":{ "fields":["remote_ip"], "query":"alfred +way" } } }
Term Query
- 将查询语句作为整个单词进行查询,即不对查询语句做分词处理,如下所示:
GET test_index_index/_search { "query":{ "term":{ "remote_ip":"171.22.12.14" } } }
Range Query
- 范围查询主要针对数值和日期类型,如下所示:
GET test_index_index/_search { "query":{ "range":{ "response":{#找出响应状态码大于10,小于300的文档 "gt": 10, "lte":300 } } } }
针对日期的查询如下所示:
GET test_index_index/_search { "query":{ "range":{ "birth":{ "gt": "1990-01-01", "lte":"now-2h", "gt":"2019-01-01||+1M/d" } } } }