elasticSearch之API:索引运行

一、索引操作

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index.html

1、创建索引

索引命名必须小写,不能以下划线开头
格式: PUT /索引名称

#创建索引
PUT /es_db
#创建索引时可以设置分片数和副本数
PUT /es_db
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
#修改索引配置
PUT /es_db/_settings
{
"index" : {
"number_of_replicas" : 1
}
}

在这里插入图片描述

2、查询索引

格式: GET /索引名称

#查询索引
GET /es_db
#es_db是否存在
HEAD /es_db

在这里插入图片描述

3、删除索引

格式: DELETE /索引名称

DELETE /es_db

4、ES倒排索引

当数据写入 ES 时,数据将会通过 分词 被切分为不同的 term,ES 将 term 与其对应的文档列表建立一种映射关系,这种结构就是 倒排索引。如下图所示:
在这里插入图片描述
为了进一步提升索引的效率,ES 在 term 的基础上利用 term 的前缀或者后缀构建了 term index, 用于对 term 本身进行索引,ES 实际的索引结构如下图所示:
在这里插入图片描述
这样当我们去搜索某个关键词时,ES 首先根据它的前缀或者后缀迅速缩小关键词的在 term dictionary 中的范围,大大减少了磁盘IO的次数。

单词词典(Term Dictionary) :记录所有文档的单词,记录单词到倒排列表的关联关系
常用字典数据结构:https://www.cnblogs.com/LBSer/p/4119841.html

倒排列表(Posting List)-记录了单词对应的文档结合,由倒排索引项组成

倒排索引项(Posting):
文档ID
词频TF–该单词在文档中出现的次数,用于相关性评分
位置(Position)-单词在文档中分词的位置。用于短语搜索(match phrase query)
偏移(Offset)-记录单词的开始结束位置,实现高亮显示
在这里插入图片描述
Elasticsearch 的JSON文档中的每个字段,都有自己的倒排索引。
可以指定对某些字段不做索引:
优点︰节省存储空间
缺点: 字段无法被搜索

5、文档映射Mapping

(1)字段类型

核心类型:

  • 字符串(string)
    text,keyword
  • 数字类型(Numeric)
    long,integer,short,byte,double,float,half_float,scaled_float
  • 日期类型(Date)
    data
  • 布尔类型(Boolean)
    boolean
  • 二进制类型(binary)
    binary

复合类型:

  • 数组类型(Array)
    Array支持不针对特定的类型
  • 对象类型(Object)
    Object用于单JSON对象
  • 嵌套类型(Nested)
    nested用于JSON对象数组

地理类型(Geo):

  • 地理坐标(Geo-points)
    geo_point用于描述经纬度坐标
  • 地理图形(Geo-Shape)
    geo_shape用于描述复杂形状,如多边形

特定类型:

  • IP类型
    ip用于描述ipv4和ipv6
  • 补全类型(Completion)
    completion提供自动完成提示
  • 令牌计数类型(Token count)
    token_count用于统计字符串中的词条数量
  • 附件类型(attachment)
    参考mapper-attachements插件,支持将附件如Microsoft Office格式,Open Document格式,ePub,HTML等等索引为attachment数据类型
  • 抽取类型(Percolator)
    接受特定领域查询语言(query-dsl)的查询

多字段:
通常用于为不同目的用不同的方法索引同一个字段。例如,string字段可以映射为一个text字段用于全文检索,同样可以映射为一个keyword字段用于排序和聚合。另外,你可以使用standard analyzer,english analyzer,french analyzer来索引一个text字段。
这就是muti-fields的目的。大多数的数据类型通过fields参数来支持muti-fields。

(2)映射

Mapping(映射)
Mapping 是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和 索引的。
比如,使用 mapping 来定义:

 哪些字符串属性应该被看做全文本属性(full text fields)。
 哪些属性包含数字,日期或者地理位置。
 文档中的所有属性是否都能被索引(_all 配置)。
 日期的格式。
 自定义映射规则来执行动态添加属性。

// 查看 mapping 信息(列出该索引所有字段的类型):
GET bank/_mapping
// 修改 mapping 信息
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html

mapping其实不需要手动定义,在插入数据时会自动猜测映射类型:
布尔型:trye或者false : boolean
整数:123 : long
浮点数:123.45 : double
字符串,有效日期:2022-06026 : date
字符串:learn elasticSearch : string

(3)动静态映射

Mapping类似数据库中的schema的定义,作用如下:
定义索引中的字段的名称
定义字段的数据类型,例如字符串,数字,布尔等
字段,倒排索引的相关配置(Analyzer)
ES中Mapping映射可以分为动态映射和静态映射

动态映射:
在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射(即关系型数据库的表、字段等),在文档写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射

静态映射:
静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射。

动态映射(Dynamic Mapping)的机制,使得我们无需手动定义Mappings,Elasticsearch会自动根据文档信息,推算出字段的类型。但是有时候会推算的不对,例如地理位置信息。当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询

(4)Dynamic Mapping类型自动识别

在这里插入图片描述

#删除原索引
DELETE /user
#创建文档(ES根据数据类型, 会自动创建映射)
PUT /user/_doc/1
{
"name":"cxf",
"age":32,
"address":"长沙麓谷"
}
#获取文档映射
GET /user/_mapping

在这里插入图片描述

(5)后期更改Mapping的字段类型

新增加字段
dynamic设为true时,一旦有新增字段的文档写入,Mapping 也同时被更新
dynamic设为false,Mapping 不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
dynamic设置成strict(严格控制策略),文档写入失败,抛出异常

在这里插入图片描述
对已有字段,一旦已经有数据写入,就不再支持修改字段定义
Lucene 实现的倒排索引,一旦生成后,就不允许修改
如果希望改变字段类型,可以利用 reindex API,重建索引

原因:
如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
但是如果是增加新的字段,就不会有这样的影响

测试:

PUT /user
{
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": "true"
}
}
}
}
# 插入文档报错,原因为age为新增字段,会抛出异常
PUT /user/_doc/1
{
"name":"cxf",
"age":32,
"address":{
"province":"湖南",
"city":"长沙"
}
}

dynamic设置成strict,新增age字段导致文档插入失败

在这里插入图片描述

# 修改dynamic后再次插入文档成功
#修改daynamic
PUT /user/_mapping
{
"dynamic":true
}
# 添加新的字段映射
# 解释:index:false,默认所有的字段的index都是true,为false是不会被索引的不会被查出来,也就是相当于一个冗余字段。
PUT /my-index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword",
"index": false
}
}
}

(6)对已有字段的mapping修改

具体方法:
1)如果要推倒现有的映射, 你得重新建立一个静态索引
2)然后把之前索引里的数据导入到新的索引里
3)删除原创建的索引
4)为新索引起个别名, 为原索引名

PUT /user2
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"address": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
POST _reindex
{
"source": {
"index": "user"
},
"dest": {
"index": "user2"
}
}
DELETE /user
PUT /user2/_alias/user
GET /user

注意: 通过这几个步骤就实现了索引的平滑过渡,并且是零停机

也可以使用条件:
在这里插入图片描述

(7)常用Mapping参数配置

(7.1)index

index: 控制当前字段是否被索引,默认为true。如果设置为false,该字段不可被搜索

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"index": false
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
PUT /user/_doc/1
{
"name":"cxf",
"address":"广州白云山公园",
"age":30
}
GET /user
GET /user/_search
{
"query": {
"match": {
"address": "广州"
}
}
}

在这里插入图片描述

(7.2)index_options

有四种不同基本的index options配置,控制倒排索引记录的内容:
docs : 记录doc id
freqs:记录doc id 和term frequencies(词频)
positions: 记录doc id / term frequencies / term position
offsets: doc id / term frequencies / term posistion / character offsets

text类型默认记录postions,其他默认为 docs。记录内容越多,占用存储空间越大

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "text",
"index_options": "offsets"
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}

(7.3)null_value

null_value: 需要对Null值进行搜索,只有keyword类型支持设计Null_Value

DELETE /user
PUT /user
{
"mappings" : {
"properties" : {
"address" : {
"type" : "keyword",
"null_value": "NULL"
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
PUT /user/_doc/1
{
"name":"fox",
"age":32,
"address":null
}
GET /user/_search
{
"query": {
"match": {
"address": "NULL"
}
}
}

在这里插入图片描述

(7.4)copy_to

copy_to设置:将字段的数值拷贝到目标字段,满足一些特定的搜索需求。copy_to的目标字段不出现在_source中。

# 设置copy_to
DELETE /address
PUT /address
{
"mappings" : {
"properties" : {
"province" : {
"type" : "keyword",
"copy_to": "full_address"
},
"city" : {
"type" : "text",
"copy_to": "full_address"
}
}
},
"settings" : {
"index" : {
"analysis.analyzer.default.type": "ik_max_word"
}
}
}
PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}
GET /address/_search
{
"query": {
"match": {
"full_address": {
"query": "湖南常德",
"operator": "and"
}
}
}
}

(8)Index Template

Index Templates可以帮助你设定Mappings和Settings,并按照一定的规则,自动匹配到新创建的索引之上

模版仅在一个索引被新创建时,才会产生作用。修改模版不会影响已创建的索引
你可以设定多个索引模版,这些设置会被“merge”在一起
你可以指定“order”的数值,控制“merging”的过程

PUT /_template/template_default
{
"index_patterns": ["*"],
"order": 0,
"version": 1,
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
PUT /_template/template_test
{
"index_patterns": ["test*"],
"order": 1,
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1
},
"mappings": {
"date_detection": false,
"numeric_detection": true
}
}

(9)lndex Template的工作方式

当一个索引被新创建时:
应用Elasticsearch 默认的settings 和mappings
应用order数值低的lndex Template 中的设定
应用order高的 Index Template 中的设定,之前的设定会被覆盖
应用创建索引时,用户所指定的Settings和 Mappings,并覆盖之前模版中的设定

#查看template信息
GET /_template/template_default
GET /_template/temp*
PUT /testtemplate/_doc/1
{
"orderNo": 1,
"createDate": "2022/01/01"
}
GET /testtemplate/_mapping
GET /testtemplate/_settings
PUT /testmy
{
"mappings": {
"date_detection": true
}
}
PUT /testmy/_doc/1
{
"orderNo": 1,
"createDate": "2022/01/01"
}
GET /testmy/_mapping

(10)Dynamic Template

Dynamic Tempate定义在某个索引的Mapping中。

#Dynaminc Mapping 根据类型和字段名
DELETE my_index
PUT my_index/_doc/1
{
"firstName":"Ruan",
"isVIP":"true"
}
GET my_index/_mapping
DELETE my_index
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"
}
}
}
]
}
}
#结合路径
PUT /my_test_index
{
"mappings": {
"dynamic_templates": [
{
"full_name":{
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping":{
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
PUT /my_test_index/_doc/1
{
"name":{
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
}
GET /my_test_index/_search
{
"query": {
"match": {
"full_name": "John"
}
}
}

posted @ 2025-11-23 14:39  yangykaifa  阅读(0)  评论(0)    收藏  举报