此章依然是es的restfulAPI,因为es的映射是可选的操作,又由于其比较重要,所以单拿一节告别说明。除了API还有字段定义(相当于mysql的create table)相关的知识点,这些对优化es比较有意义。
一、概要说明
简单示例
对索引字段的定义,包括数据类型、存储属性、分析器、词向量等。
put customer
{
"mappings":{
"properties":{
"fields":{"type":"text"},
"created":{
"type":"date",
"format":"string-date_optiional_time||epoch_millis"
}
}
}
}
API
查看映射
get /king/_mapping/
{
"king": {
"mappings": {
"properties": {
"address": {
"type": "text"
},
"age": {
"type": "long"
},
"name": {
"type": "keyword"
}
}
}
}
}
更改映射
可以向已有映射中增加字段,但你不能修改它。如果一个字段在映射中已经存在,这可能意味着那个字段的数据已经被索引。如果你改变了字段映射,那已经被索引的数据将错误并且不能被正确的搜索到。不能把已有字段的类型那个从 analyzed 改到 not_analyzed。
put customer
{
"properties":{
"fields":{"type":"text"},
}
}
测试映射
get /king/_analyze?field=tag //输出内容是tage字段的分词结果
二、数据类型
基本类型
- long:
- integer:
- short:
- byte:
- double:
- float:
- half_float(半精度浮点数):
- scaled_float(可变浮点数):
布尔类型-boolean
- boolean:可接受值为true|false,或带双引号的"true"|"false"
空字段
在es中没有Null值,下面四种情况将不会被索引
"empty_string":""
"null_value": null,
"empty_array": [],
"array_with_null_value":[ null ]
数组类型
- 没有专门的数组类型,默认情况下,任何字段都可以存储数组,但值必须具有相同的数据类型,比如["ld", "hm"]
日期类型-date
没有专门的日期类型,但下列情况会在ES中转为UTC并存储为毫秒数。可以用string-date_optiional_time||epoch_millis 来指定其格式,如果有多个值在索引存储时会按个试验。如果没有则异常。
- 包含格式化日期的字符串,如2021-01-21
- 一个表示自纪元以来毫秒数的长整形数字
- 表示从纪元开始的秒数的整数
关键字-keyword
用keyword设置,特点是不再分词,直接作为一个Term索引存在,检索时只能用精确值检索
put customer
{
"mappings":{
"properties":{
"fields":{"type":"text"},
"created":{
"type":"date",
"format":"string-date_optiional_time||epoch_millis"
},
"tags":{"id":"keyword"}
}
}
}
文本-text
这种类型会进行解析、分词,索引的是解析后的term,相当于富文本。
地理位置-geo_point
put customer
{
"mappings":{
"properties":{
"location":{"type":"geo_point"}
}
}
}
插入数据
put customer/_doc/1
{
"location":{
"lat":21.21,
"lon":33.33
}
}
//以下两种写法也可以
{
"location":"21.21, 33.33"
}
{
"location":["21.21, 33.33"]
}
查询数据-只能按边框来查询
get customer/_search
{
"query":{
"geo_bounding_box":{
"top_left":{
"lat":22,
"lon":22
},
"bottom_right":{
"lat":22,
"lon":22
}
}
}
}
三、字段属性
映射属性决定了字段的存储、索引、搜索、分析等方面的功能和特征。
Index属性
是否对字段进行索引,未索引的字段不能用来搜索、排序、聚合。默认为true。
put customer
{
"mappings":{
"properties":{
"location":{"type":"geo_point", "index": true},
}
}
}
//可选值有:
1、analyzed:首先分析这个字符串,然后索引。换言之,以全文形式索引此字段。
2、not_analyzed:索引这个字段,使之可以被搜索,但是索引内容和指定值一样。不分析此字段。
3、no:不索引这个字段。这个字段不能为搜索到。
store属性
默认情况下,字段值都是被索引的,存储在_source中,但不会被存储。意味着可以查询字段,但无法检索原始字段。它主要的用处是用于过滤,比如做为主存储时,一个具有title, data和非常大的content的文档,业务上只按标题和日期检索,这里就没必要从_source中提取了。
put customer
{
"mappings":{
"properties":{
"title":{"type":"text", "store": true},
"date":{"type":"date", "store": true},
"content":{"type":"date"},
}
}
}
//检索
GET customer/_search
{
"stored_fields":["title", "date"]
}
analyze属性
表示索引和检索时采用的分析方法。常用的就是standard 分析器是用于全文字段的默认分析器,对于大部分西方语系来说是一个不错的选择。它考虑了以下几点:
- standard 分词器,在词层级上分割输入的文本。
- standard 表征过滤器,被设计用来整理分词器触发的所有表征(但是目前什么都没做)。
- lowercase 表征过滤器,将所有表征转换为小写。
- stop 表征过滤器,删除所有可能会造成搜索歧义的停用词,如 a , the , and , is 。
所以一个分析器由以下三个部分组成,这三个部分在索引时会依次执行
字符过滤器
字符过滤器是让字符串在被分词前变得更加“整洁”。例如,如果我们的文本是 HTML 格式,它可能会包含一些我们不 想被索引的 HTML 标签,诸如 <p> 或 <div> 。
我们可以使用 html_strip 字符过滤器 来删除所有的 HTML 标签,并且将 HTML 实体转换成对应的 Unicode 字符, 比如将 Á 转成 Á 。一个分析器可能包含零到多个字符过滤器。
分词器
一个分析器 必须 包含一个分词器。分词器将字符串分割成单独的词(terms)或表征(tokens)。 standard 分析器使 用 standard 分词器将字符串分割成单独的字词,删除大部分标点符号,但是现存的其他分词器会有不同的行为特 征。
例如, keyword 分词器输出和它接收到的相同的字符串,不做任何分词处理。[ whitespace 分词器]只通过空格来分割 文本。[ pattern 分词器]可以通过正则表达式来分割文本。
表征过滤器
分词结果的 表征流 会根据各自的情况,传递给特定的表征过滤器。表征过滤器可能修改,添加或删除表征。我们已经提过 lowercase 和 stop 表征过滤器,但是 Elasticsearch 中有更 多的选择。 stemmer 表征过滤器将单词转化为他们的根形态(root form)。 ascii_folding 表征过滤器会删除变音符 号,比如从 très 转为 tres 。 ngram 和 edge_ngram 可以让表征更适合特殊匹配情况或自动完成。
自定义分析器
通用语法
"settings":{
"analysis":{
"char_filter":{..custom character filters...},
"tokenizer":{ custom tokenizers},
"filter":{custom token filters},
"analyzer":{custom analyzers}
}
}
put customer
{
"settings": {
"analysis": { //解析器1
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20
}
},
"analysis": { //自定义解析器1
"filter": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase", "autocomplete_filter"
]
}
}
}
},
"mapping": {
"properties": {
"userName": {
"type": "text",
"analyzer": "autocomplete", //索引时使用autocomplete解析器,它会把存入的字符拆的很碎,比如存储ld,索引时会拆成, l, d, ld
"search_analyzer": "standard" //搜索时使用standard解析器,查询时按空格来拆词
}
}
}
}
}
doc_values属性
默认情况下,倒排索引允许查询在唯一排序的Term列表中的查找搜索Term,并从中可以立即访问包含此Term的文档列表。但排序、聚合时是不需要查找Term和文档的,doc_values是磁盘上的数据结构,在文档索引时创建,值基本与_source相同,以列的方式存储。默认情况下是开启的,如不需要排序和聚合,可关闭相应字段的此功能。
put customer
{
"mappings":{
"properties":{
"title":{"type":"text", "store": true, "doc_values":false},
"date":{"type":"date", "store": true}
}
}
}