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

elasticsearch中的字段类型/mapping参数

程序员文章站 2022-07-09 13:48:27
...

查看表结构的定义 
GET /testindex/_mapping 
GET /testindex/testtable/_mapping

(一)核心数据类型:

(1)string: 默认会被分词 
string类型包括:text 和 keyword

一个完整示例如下 :


 "status": {
          "type":  "string", //字符串类型
          "index": "analyzed"//分词,不分词是:not_analyzed ,设置成no,字段将不会被索引
          "analyzer":"ik"//指定分词器
          "boost":1.23//字段级别的分数加权
           "doc_values":false//对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存
            "fielddata":{"format":"disabled"}//针对分词字段,参与排序或聚合时能提高性能,不分词字段统一建议使用doc_value
            "fields":{"raw":{"type":"string","index":"not_analyzed"}} //可以对一个字段提供多种索引模式,同一个字段的值,一个分词,一个不分词
            "ignore_above":100 //超过100个字符的文本,将会被忽略,不被索引
            "include_in_all":ture//设置是否此字段包含在_all字段中,默认是true,除非index设置成no选项
            "index_options":"docs"//4个可选参数docs(索引文档号) ,freqs(文档号+词频),positions(文档号+词频+位置,通常用来距离查询),offsets(文档号+词频+位置+偏移量,通常被使用在高亮字段)分词字段默认是position,其他的默认是docs
            "norms":{"enable":true,"loading":"lazy"}//分词字段默认配置,不分词字段:默认{"enable":false},存储长度因子和索引时boost,建议对需要参与评分字段使用 ,会额外增加内存消耗量
             "null_value":"NULL"//设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词
             "position_increament_gap":0//影响距离查询或近似查询,可以设置在多值字段的数据上火分词字段上,查询时可指定slop间隔,默认值是100
              "store":false//是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值
               "search_analyzer":"ik"//设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
                "similarity":"BM25"//默认是TF/IDF算法,指定一个字段评分策略,仅仅对字符串型和分词类型有效
                "term_vector":"no"//默认不存储向量信息,支持参数yes(term存储),with_positions(term+位置),with_offsets(term+偏移量),with_positions_offsets(term+位置+偏移量) 对快速高亮fast vector highlighter能提升性能,但开启又会加大索引体积,不适合大数据量用
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

string类型默认是analyzed,如果我们想映射字段为确切值,我们需要设置它为not_analyzed:

{
    "demo": {
        "type":     "string",
        "index":    "not_analyzed"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

ES默认的分词器为standard, 想要改变默认分词器为ik分词器, 可以在config/elasticsearch.yml文件中添加如下配置即可: 
index.analysis.analyzer.default.type:ik

测试分词: 
GET _analyze?text=Black-cats

GET /testindex/_analyze 

“text”:”Black-cats” 
}

测试字段中的分词: 
GET /testindex/_analyze?field=demo&text=Black-cats

GET /testindex/_analyze 

“field”:”demo”, 
“text”:”Black-cats” 
}

(2)数字类型主要如下几种: 
long:64位存储 
integer:32位存储 
short:16位存储 
byte:8位存储 
double:64位双精度存储 
float:32位单精度存储

支持参数:

coerce:true/false 如果数据不是干净的,将自动会将字符串转成合适的数字类型,字符串会被强转成数字,浮点型会被转成整形,经纬度会被转换为标准类型 
boost:索引时加权因子 
doc_value:是否开启doc_value 
ignore_malformed:false(错误的数字类型会报异常)true(将会忽略) 
include_in_all:是否包含在_all字段中 
index:not_analyzed默认不分词 
null_value:默认替代的数字值 
precision_step:16 额外存储对应的term,用来加快数值类型在执行范围查询时的性能,索引体积相对变大 
store:是否存储具体的值

(3)其他简单类型 
日期类型: 
date 
布尔类型: 
boolean 
字节类型: 
binary

(4)复合类型

数组类型:没有明显的字段类型设置,任何一个字段的值,都可以被添加0个到多个,要求,他们的类型必须一致: 
对象类型:存储类似json具有层级的数据 
嵌套类型:支持数组类型的对象Aarray[Object],可层层嵌套

(5)地理类型

geo-point类型: 支持经纬度存储和距离范围检索 
geo-shape类型:支持任意图形范围的检索,例如矩形和平面多边形

(6)专用类型 
ipv4类型:用来存储IP地址,es内部会转换成long存储 
completion类型:使用fst有限状态机来提供suggest前缀查询功能 
token_count类型:提供token级别的计数功能 
mapper-murmur3类型:安装sudo bin/plugin install mapper-size插件,可支持_size统计_source数据的大小 
附件类型:需要 https://github.com/elastic/elasticsearch-mapper-attachments开源es插件支持,可存储office,html等类型

(7)多值字段: 
一个字段的值,可以通过多种分词器存储,使用fields参数,支持大多数es数据类型

(二)Mapping 参数列表,上面文章出现过的不再解释:

copy_to: 与solr里面的copy_field字段功能一样,支持拷贝某个字段的值到集中的一个字段里面 
properties:对象字段和嵌套字段可以包含子字段,这些属性可以被添加进去,例子如下

创建表结构

PUT /testindex/_mapping/testtable
{
    "testtable": {
             "_all": {
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word",
            "term_vector": "no",
            "store": "false"
        },
        "properties": {
            "demo": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word",
                "include_in_all": "true",
                "boost": 8
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

–给表testtable添加一个字段demo

PUT testindex/_mapping/testtable
{
  "properties": {
    "demo": {
      "type": "text"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

修改字段类型: 
无法修改字段类型。

删除字段: 
无法删除

修改mapping 

Elasticsearch的mapping一旦创建,只能增加字段,而不能修改已经mapping的字段。但现实往往并非如此啊,有时增加一个字段,就好像打了一个补丁,一个可以,但是越补越多,最后自己都觉得惨不忍睹了。怎么办??

这里有一个方法修改mapping,那就是重新建立一个index,然后创建一个新的mapping。你可能会问,这要是在生产环境,可行吗?答案是,如果你一开始就采取了合适的设计,这个完全是可以做到平滑过渡的。

采取什么合理设计呢?就是我们的程序访问索引库时,始终使用同义词来访问,而不要使用真正的indexName。在reindex完数据之后,修改之前的同义词即可。明白了吗?

参考上面的思路,我们来一步一步做。

step1、创建一个索引,这个索引的名称最好带上版本号,比如my_index_v1,my_index_v2等。

step2、创建一个指向本索引的同义词。

curl -XPOST localhost:9200/_aliases -d '
{
    "actions": [
        { "add": {
            "alias": "my_index",
            "index": "my_index_v1"
        }}
    ]
}
'

 此时,你可以通过同义词my_index访问。包括创建索引,删除索引等。

step3,需求来了,需要更改mapping了,此时,你需要创建一个新的索引,比如名称叫my_index_v2(版本升级).,在这个索引里面创建你新的mapping结构。然后,将新的数据刷入新的index里面。在刷数据的过程中,你可能想到直接从老的index中取出数据,然后更改一下格式即可。如何遍历所有的老的index数据,请参考 这里 。

step4,修改同义词。将指向v1的同义词,修改为指向v2。http接口如下:

curl -XPOST localhost:9200/_aliases -d '
{
    "actions": [
        { "remove": {
            "alias": "my_index",
            "index": "my_index_v1"
        }},
        { "add": {
            "alias": "my_index",
            "index": "my_index_v2"
        }}
    ]
}
'

 step5,删除老的索引。

curl -XDELETE localhost:9200/my_index_v1

 除此之外,还有几个其他的方法也可以更改mapping。

1、修改程序,添加字段。

就是说,你可以在mapping中增加一个新的字段,然后你对新的字段进行访问统计搜索。这个就要修改两个地方,一个是修改mapping增加字段,还有就是修改你的程序,把字段改成新的字段。

2、更改字段类型为multi_field。

multi_field允许为一个字段设置多个数据类型。应用multi_field的一个最典型的场景是:一个类型定义为analyed,这个字段可以被搜索到,一个类型定义为不分词,这个字段用于排序。

任何字段都可以被更新为multi_field(类型为object和nested的类型除外)。假设现在有一个字段,名字叫created,类型现在为string。

{     "created": { "type": "string"} }

 我们可以将它增加一种类型,使他既能被当做字符串又能当做日期型。

curl -XPUT localhost:9200/my_index/my_type/_mapping -d '
{
    "my_type": {
        "properties": {
            "created": {
                "type":   "multi_field",
                "fields": {
                    "created": { "type": "string" },
                    "date":    { "type": "date"   }
                }
            }
        }
    }
}
'

采用标准的重建索引方式的时候,我们推荐大家为每一个type都建立一个索引同义词,即便在同一个索引库中的多个type,也推荐使用建立一个同义词来访问。即一个index里面包含一个type,因为在elasticsearch中,跨index查询数据是很方便的。这样,我们就可以在reindex一个type后,立即将type生效,而不是将index下面所有的type都重建完后,同义词才能生效。