1、ElasticSearch安装,新增删除索引,映射参数详解,文档增删改,分词器详解

  • 一、什么是Elasticsearch
  • 1.1 、ES搜索快的原因?
  • 二、ES中一些名词概念
  • 2.1、文档(document)
  • 2.2、索引(index)
  • 2.3、类型(type)
  • 2.4、映射(mapping)
  • 2.5、字段(field)
  • 2.6、主键(ID)
  • 三、ES安装
  • 3.1 安装
  • 3.2 安装问题排查
  • 四、ES索引(index)操作
  • 4.1 创建索引
  • 4.2 查看索引
  • 4.3 删除索引
  • 五、ES映射(mappings)操作
  • 5.1 动态映射
  • 5.2 静态映射
  • 5.3 映射数据说明
  • 5.4 特殊的映射属性说明
  • 5.4 新增映射字段属性
  • 六、ES文档操作
  • 6.1 创建文档
  • 6.2 查询文档
  • 6.3 修改文档
  • 6.4 修改文档中的某个字段
  • 6.5 删除文档
  • 七、分词器(Analyzer)
  • 7.1 内置分词器
  • 7.2 中文分词器
  • 7.2.1 安装分词器
  • 7.2.2 扩展词汇(自定义词汇)
  • 7.3 分词器中的一些用法
  • 7.3.1 _analyze用法
  • 7.3.2 默认分词器说明
  • 7.3.3 查看文档中某一个字段的分词结果


一、什么是Elasticsearch

Elaticsearch简称为 ES, ES是一个开源的分布式搜索引擎,可用于实现全文搜索、日志分析、业务分析等应用。它是建立在Apache Lucene搜索引擎基础上的,提供了高效的搜索、分析和聚合功能,并支持实时数据处理和可伸缩性。

1.1 、ES搜索快的原因?


1、ES使用了倒排索引这种数据结构来快速查找文档。倒排索引是一种针对文本搜索而优化的数据结构,它将每个词与出现这个词的文档列表关联起来,这样就可以快速查找包含某些词的文档。


2、ES使用了分布式系统的优势,可以利用多台机器的计算能力来处理查询。它将索引分成若干个分片,并在多台机器上进行分布式存储,这样就可以并行处理查询,提升查询效率。


3、ES还有很多优化查询的功能,比如布尔查询、聚合查询、嵌套查询等,这些功能都可以帮助快速定位符合查询条件的文档。


二、ES中一些名词概念

2.1、文档(document)


文档是存储在Elasticsearch中的一个JSON格式的字符串。它就像在关系数据库中表的一行。每个存储在索引中的一个文档都有一个类型和一个ID,每个文档都是一个JSON对象,存储了零个或多个字段或键值对。原始的JSON文档被存储在一个叫做_source的字段中,当搜索文档的时候默认返回的就是这个字段。

2.2、索引(index)


索引是具有相同结构的文档集合。在系统上索引的名字全部为小写,通过这个索引名字可以用来执行索引、搜索、更新和删除操作。索引类似Mysql中的库。

2.3、类型(type)


类型是索引的逻辑分区。一般情况下,一种类型被定义为具有一组公共字段的文档。

注:elasticsearch7已经移除type概念,不再支持指定索引类型,默认索引类型是_doc。

2.4、映射(mapping)


类似于mysql中的表结构。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,每一个索引都有一个映射,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)

2.5、字段(field)


字段类似关系数据库中表的字段,每一个文档包含零个或多个字段。

2.6、主键(ID)


唯一标识,如果没有提供,系统会自动生成。文档的ID必须是唯一的。

三、ES安装

本文介绍Windows环境下安装ES,官网下载地址,由于公司使用的是7.8版本,我们这就安装7.8版本的ES。

es为什么可以用作搜索引擎 es搜索引擎原理详解_大数据

3.1 安装


1、把文件解压,进入到bin目录下,双击执行elasticsearch.bat文件,即是启动成功。如下图即是启动成功。

注意:es启动会占用两个端口,9200和9300,9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http协议 RESTful 端口

es为什么可以用作搜索引擎 es搜索引擎原理详解_es为什么可以用作搜索引擎_02


访问地址: http://localhost:9200, 下面中的number就表示ES版本7.8.0


es为什么可以用作搜索引擎 es搜索引擎原理详解_es为什么可以用作搜索引擎_03

3.2 安装问题排查

1、ES是使用 java 开发的,且 7.8 版本的 ES 需要 JDK 版本 1.8 及以上,这里建议用JDK1.8

2、启动ES时,双击elasticsearch.bat闪退,大概率是ES占用内存太大导致,修改ES目录的/config/jvm.options文件,如下图。

注意: 默认占用内存是1g,一般电脑是没问题的

es为什么可以用作搜索引擎 es搜索引擎原理详解_es为什么可以用作搜索引擎_04

四、ES索引(index)操作

4.1 创建索引

1、创建索引: PUT请求,http://127.0.0.1:9200/shopping,表示创建一个名为shopping的索引。

#返回数据
{
	"acknowledged": true,  #请求接口成功
	"shards_acknowledged": true, #分片操作成功 
	"index": "shopping" #创建的索引名称
}

4.2 查看索引

1、查看指定索引: GET请求,http://127.0.0.1:9200/shopping

{
	"shopping": {
		"aliases": {},
		"mappings": {},
		"settings": {
			"index": {
				"creation_date": "1689079823941",  #索引创建时间
				"number_of_shards": "1",   #索引分片数量
				"number_of_replicas": "1",  #索引副本数量
				"uuid": "033uQUgwRkufdi4QPI9cEQ",
				"version": {
					"created": "7080099"
				},
				"provided_name": "shopping"
			}
		}
	}
}

2、查看所有索引: GET请求,http://127.0.0.1:9200/_cat/indices?v

health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   shopping2 _7zn-x_WTZGCnC223lj3VQ   1   1          0            0       208b           208b
yellow open   shopping  033uQUgwRkufdi4QPI9cEQ   1   1          0            0       208b           208b

es为什么可以用作搜索引擎 es搜索引擎原理详解_搜索引擎_05

4.3 删除索引

1、删除指定索引: DELETE请求,http://127.0.0.1:9200/shopping

{
	"acknowledged": true #请求接口成功
}

五、ES映射(mappings)操作

5.1 动态映射

动态映射的意思是在创建索引后,不用创建映射,直接插入文档,根据插入的文档判断数据类型自动创建映射关系,这种就叫动态映射。


#1、创建索引,PUT请求
http://127.0.0.1:9200/student

#2、查看索引映射,GET请求,发现没用映射关系
http://127.0.0.1:9200/student/_mapping
#返回数据
{
    "student22": {
        "mappings": {}
    }
}

#3、插入文档  POST请求
http://127.0.0.1:9200/student/_doc/1001
#请求体
{
 "name":"张刚",
 "sex":"男",
 "age":20
} 
#返回数据
{
    "_index": "student",
    "_type": "_doc",
    "_id": "1001",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

#4、再次查看映射,发现有映射关系了。返回映射数据
{
    "student": {
        "mappings": {
            "properties": {
                "age": {
                    "type": "long"
                },
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "sex": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

5.2 静态映射

静态映射的意思就是在定义索引后,在把索引中的所有字段类型通过映射提前定义好,那么以后往索引中加数据和字段时,就只能按照规定好的加。

注意:如果加了类型不对等的数据,会报 400 错误。

#1、创建索引,PUT请求
http://127.0.0.1:9200/student2
#2、创建索引映射关系,PUT请求
http://127.0.0.1:9200/student2/_mapping
#请求body
{
	 "properties": {
		 "name":{
			 "type": "text",
			 "index": true
		 },
		 "sex":{
			 "type": "text",
			 "index": false
		 },
		 "age":{
			 "type": "long",
			 "index": false
		 }
	 } 
}

#3、查看索引映射关系,GET请求
http://127.0.0.1:9200/student2/_mapping
#返回数据
{
    "student2": {
        "mappings": {
            "properties": {
                "age": {
                    "type": "long",
                    "index": false
                },
                "name": {
                    "type": "text"
                },
                "sex": {
                    "type": "text",
                    "index": false
                }
            }
        }
    }
}

注意:传上面那种body,必须先创建索引,在创建映射关系。下面是索引和映射可以一步做成,区别是body体不一样

#PUT请求
http://127.0.0.1:9200/student3
#body体
{
	"settings": {},
	"mappings": {
		"properties": {
			"age": {
				"type": "long",
				"index": false
			},
			"name": {
				"type": "text",
				"analyzer": "ik_smart"
			},
			"sex": {
				"type": "text",
				"index": false
			}
		}
	}
}

5.3 映射数据说明

type:类型,ES中支持的数据类型非常丰富,说几个关键的:

    String 类型,又分两种:
        text:可分词
        keyword:不可分词,数据会作为完整字段进行匹配
    Numerical:数值类型,分两类
        基本数据类型:long、integer、short、byte、double、float、half_float
        浮点数的高精度类型:scaled_float
    Date:日期类型
    Array:数组类型
    Object:对象

index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。

    true:字段会被索引,则可以用来进行搜索
    false:字段不会被索引,不能用来搜索

store:是否将数据进行独立存储,默认为 false

    原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。

analyzer:指定分词器

5.4 特殊的映射属性说明

下面是我测试的时候遇到的一个映射关系,比如字段name、nickname、sex的fields属性让我很不理解,各种百度查询: 除了本身被映射为text类型,还另外为其添加了名称为keyword、type为keyword的field,这使得查询时既可以对字段本身做Match Query,也可以对author.keyword做Term Query。这里说的查询如果不理解,可以看我下一章的高级查询。

{
	"student": {
		"aliases": {},
		"mappings": {
			"properties": {
				"age": {
					"type": "long"
				},
				"name": {
					"type": "text",
					"fields": {
						"keyword": {
							"type": "keyword",
							"ignore_above": 256
						}
					}
				},
				"nickname": {
					"type": "text",
					"fields": {
						"keyword": {
							"type": "keyword",
							"ignore_above": 256
						}
					}
				},
				"sex": {
					"type": "text",
					"fields": {
						"keyword": {
							"type": "keyword",
							"ignore_above": 256
						}
					}
				}
			}
		},
		"settings": {
			"index": {
				"creation_date": "1689343383825",
				"number_of_shards": "1",
				"number_of_replicas": "1",
				"uuid": "dK-EfgXnST2hiiOrLddH4w",
				"version": {
					"created": "7080099"
				},
				"provided_name": "student"
			}
		}
	}
}

5.4 新增映射字段属性

注意:映射属性一旦创建,是不可以修改的,但是可以新增字段映射属性。

#PUT请求,为新增字段content添加映射
http://127.0.0.1:9200/student/_mapping

{
    "properties": {
        "content": {
            "type": "text",
            "index": true
        }
    }
}

六、ES文档操作

6.1 创建文档

#POST请求,1001代表文档ID
http://127.0.0.1:9200/student/_doc/1001
#请求body
{
 "age":18,
 "name":"张刚",
 "sex":"男"
}

6.2 查询文档

#GET请求,1001代表文档ID
http://127.0.0.1:9200/student/_doc/1001
#返回数据
{
	"_index": "student",
	"_type": "_doc",
	"_id": "1001",
	"_version": 1,
	"_seq_no": 0,
	"_primary_term": 1,
	"found": true,
	"_source": {
		"age": 18,
		"name": "张刚",
		"sex": "男"
	}
}

6.3 修改文档

和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖。

#POST请求,1001代表文档ID
http://127.0.0.1:9200/student/_doc/1001
#请求body
{
 "age":19,
 "name":"张刚",
 "sex":"男"
}

6.4 修改文档中的某个字段

#POST请求
http://127.0.0.1:9200/student/_update/1001
#请求体
{
	"doc": {
		"age": 20
	}
}

6.5 删除文档

#1、根据ID删除文档
#DELETE请求
http://127.0.0.1:9200/student/_doc/1001

#2、根据条件删除多条文档
http://127.0.0.1:9200/student/_delete_by_query
{
 "query":{
  "match":{
    "age":20
  }
 } 
}

七、分词器(Analyzer)

上面说过ES是通过倒排索引来搜索的,倒排索引中的词和文档建立的关系时,这个"词"就是通过分词器进行切分的。
分词器就是当数据写入ES 时,会把数据切分成不同的词,ES把词和文档列表建立一种映射关系,生成倒排索引。
当进行搜索时,也会对输入的内容进行分词。

7.1 内置分词器

1、不同的分词器会有不同的分词结果,内置的分词器有以下几种,内置分词器对中文的分词都不够友好,一般我们都会用外置中文分词器:IK分词器



分词器

描述

standard

默认分词器,如果没有指定,则使用该分析器,

英文按单词词切分,并小写处理

simple

按照单词切分(符号被过滤), 小写处理

whitespace

按照空格切分,不转小写

stop

小写处理,停用词过滤(the,a,is)

keyword

不分词,把整个字段当做一个整体返回

7.2 中文分词器

在ES中支持中文分词器非常多 如 smartCN、IK 等,推荐的就是 IK分词器。 IK分词器是和ES版本相对应的,这里下载7.8版本的。

点击下载IK分词器



分词器

描述

ik_smart

会做最粗粒度的拆分

ik_max_word

会将文本做最细粒度的拆分

7.2.1 安装分词器

安装步骤: 将IK分词器安装包解压,然后把解压后的文件夹放入 ES 根目录下的 plugins 目录下,重启 ES 即可使用。出现下面截图且启动成功,则证明安装成功。

es为什么可以用作搜索引擎 es搜索引擎原理详解_es为什么可以用作搜索引擎_06

7.2.2 扩展词汇(自定义词汇)

1、在IK分词器安装包的config目录下,新建mydic.dic文件。注意是IK分词器的config目录,不是ES的config目录,别搞混了。

2、修改mydic.dic文件,一定要重启ES。 3、在IK分词器安装包的config目录下,找到IKAnalyzer.cfg.xml文件,然后把自定义的mydic.dic配进去。


注意: ext_dict表示的扩展词汇,如果配置有"王者荣耀",那么分词中肯定有"王者荣耀"。 ext_stopwords表示停用词,如果配置有"王者荣耀",那么分词中肯定没"王者荣耀"。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">mydic.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

3、引入扩展词汇前进行分词

#请求地址
 http://127.0.0.1:9200/_analyze
 #请求body
{
  "text":"王者荣耀",
  "analyzer":"ik_max_word"
}

#返回数据
{
    "tokens": [
        {
            "token": "王者",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "荣耀",
            "start_offset": 2,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

4、引入扩展词汇后进行分词

#mydic.dic文件内容
王者荣耀
你好
#请求地址
 http://127.0.0.1:9200/_analyze
#请求body
{
  "text":"王者荣耀",
  "analyzer":"ik_max_word"
}
#返回数据
{
    "tokens": [
        {
            "token": "王者荣耀",
            "start_offset": 0,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "王者",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 1
        },
        {
            "token": "荣耀",
            "start_offset": 2,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 2
        }
    ]
}

7.3 分词器中的一些用法

7.3.1 _analyze用法

_analyze:指定分词器和文本进行分词测试。

#GET请求
http://127.0.0.1:9200/_analyze
#请求body
{
  "analyzer": "ik_max_word",
  "text": "王者荣耀"
}
#返回数据
{
    "tokens": [
        {
            "token": "王者",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "荣耀",
            "start_offset": 2,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}



7.3.2 默认分词器说明

2、在创建索引时,指定分词器,如果不指定,默认就是standard分词器。

在查询该索引时,也能查出该索引用的分词器,如果查出的分词器是空的,默认就是standard分词器。下面创建我们指定ik_max_word分词器

#PUT请求
http://127.0.0.1:9200/shopping
#请求body,analyzer就是指定的分词器
{
  "settings": {},
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "ik_max_word" 
      }
    }
  }
}

#查询索引返回数据
{
	"shopping3": {
		"aliases": {},
		"mappings": {
			"properties": {
				"title": {
					"type": "text",
					"analyzer": "ik_max_word"
				}
			}
		},
		"settings": {
			"index": {
				"creation_date": "1689088476639",
				"number_of_shards": "1",
				"number_of_replicas": "1",
				"uuid": "eOeirsuJTpm9j5WEPkIdqg",
				"version": {
					"created": "7080099"
				},
				"provided_name": "shopping"
			}
		}
	}
}

7.3.3 查看文档中某一个字段的分词结果

#GET请求
# /{index}/{type}/{_id}/_termvectors?fields=[field]
http://127.0.0.1:9200/student/_doc/1001/_termvectors?fields=name