1 Elasticsearch简介
Elasticsearch 是一个分布式的、基于 RESTful API 的搜索和分析引擎,广泛用于大规模的数据存储和快速检索。它最初由 Shay Banon 于 2010 年开发,是开源的,并且是 Elastic Stack(通常称为 ELK Stack)的核心组成部分,另外组成部分是 Logstash、Beats(用于数据收集和处理)和 Kibana(用于数据可视化)。
2 正向索引与倒排索引
2.1 正向索引
正向索引 是指为每个文档记录其中出现的所有词汇及其位置。其结构可以理解为:每个文档对应一份词汇表,存储该文档中出现的所有词以及它们的频率、位置等信息。
特点:
按文档进行索引,存储每个文档的详细信息。
优点是容易获取某个文档中所有词汇的信息,适合于需要统计文档中词频、词位置等情况的操作。
缺点是对于查找某个词在哪些文档中出现效率较低,因为需要扫描所有文档。
2.2 倒排索引(Inverted Index)
倒排索引是搜索引擎中最常用的索引结构,用来快速查找包含某个词的所有文档。倒排索引建立了一张从词汇到文档的映射表,即对于每个词,记录它在哪些文档中出现,以及在这些文档中的位置。
特点:
按词汇进行索引,快速查找包含该词的所有文档。
优点是对搜索效率极高,尤其是当我们查询某个词或一组词时,能够快速定位所有相关文档。
缺点是需要额外的空间存储索引表。
3 msql和elasticsearch概念对比
总结
SQL 适用于需要强一致性和复杂关系查询的场景,比如财务系统、事务型数据库。
Elasticsearch 更适合大规模实时搜索、日志分析、全文检索等应用场景,具有高扩展性和近实时搜索能力。
这两者可以互补使用,SQL 处理结构化数据,ES 提供搜索和分析。
4 使用 Docker 安装 Elasticsearch + Kibana
5 操作索引库
5.1 创建索引库
访问kibana,默认端口为5601。Dev Tools 提供了一个类似于控制台的界面,你可以在其中输入并执行 Elasticsearch 的 RESTful API 请求。可通过交互式的方式执行 Elasticsearch 查询、管理索引库和执行其他集群操作。
指定 mappings 和 settings 创建索引库
在创建索引库时指定 mappings(字段类型定义)和 settings(如分片和副本的设置)。
PUT /my_index
{
"settings": {
"number_of_shards": 3, # 分片数
"number_of_replicas": 1 # 副本数
},
"mappings": {
"properties": {
"title": {
"type": "text"
},
"author": {
"type": "keyword"
},
"publish_date": {
"type": "date"
},
"price": {
"type": "float"
}
}
}
}
说明
settings:
- number_of_shards:定义索引库的分片数量。分片是用于并行处理数据的一部分。
- number_of_replicas:定义每个分片的副本数,以提高数据的可用性和容错性。
mappings:
- properties:定义字段及其类型。
- text:用于全文搜索的字段。
- keyword:用于精确值搜索的字段,通常用于过滤、排序和聚合。
- date:用于日期类型的字段。
- float:用于存储浮点数。
5.2 查询、删除、修改索引库
1.查询索引库的配置信息
GET /my_index
这将返回 my_index 的配置信息,包括分片数、副本数、字段映射等。
2. 删除索引库
DELETE /my_index
这个请求会永久删除名为 my_index 的索引库以及其中的所有数据。操作不可逆,因此删除前请确保不再需要该数据。
3. 修改索引库
在 Elasticsearch 中,索引库的某些设置是可以在创建后修改的,但有些设置(如 number_of_shards)则不能更改。以下是一些常见的可修改操作:
-
修改索引库的 settings,一些可修改的 settings 包括副本数量、刷新间隔等。
示例:修改副本数PUT /my_index/_settings { "number_of_replicas": 2 }
这个请求会将 my_index 的副本数量从当前值修改为 2。副本数可以随时修改,以增加或减少数据的冗余和查询性能。
-
修改字段映射 (mappings)
字段映射通常在索引库创建时指定,并且一旦设置,某些字段类型不能直接修改。不过,你可以通过以下方式增加新的字段:
示例:增加新的字段映射PUT /my_index/_mapping { "properties": { "new_field": { "type": "text" } } }
这个请求会在 my_index 中增加一个名为 new_field 的新字段。注意,已经存在的字段类型无法修改,你只能添加新的字段。
6 文档操作
6.1 新增、查询、删除文档
1. 新增文档
新增文档的DSL语法如下
示例 1:使用 POST 新增文档
POST /my_index/_doc/
{
"title": "Elasticsearch Basics",
"author": "John Doe",
"publish_date": "2024-01-01",
"price": 19.99
}
索引库名:my_index 是索引库的名称。
类型:_doc 是文档类型,在 Elasticsearch 7.x 之后,推荐使用 _doc 作为默认值。
自动生成 ID:不指定文档 ID 时,Elasticsearch 会为该文档自动生成一个唯一的 ID。
示例 2:使用 PUT 新增或更新文档(指定 ID)
PUT /my_index/_doc/1
{
"title": "Elasticsearch Advanced",
"author": "Jane Smith",
"publish_date": "2024-02-01",
"price": 29.99
}
指定文档 ID:文档的 ID 被明确设置为 1。如果该 ID 已存在,则该操作会更新该文档。
2. 查询文档
使用 GET 请求来检索特定的文档或执行搜索查询。
示例 1:根据 ID 查询文档
GET /my_index/_doc/1
示例 2:搜索文档(基于条件)
GET /my_index/_search
{
"query": {
"match": {
"title": "Elasticsearch"
}
}
}
搜索:通过 match 查询,Elasticsearch 会在 title 字段中搜索包含 “Elasticsearch” 关键字的文档。
示例 3:获取所有文档
GET /my_index/_search
{
"query": {
"match_all": {}
}
}
匹配所有文档:match_all 查询会返回索引库中的所有文档。
3. 删除文档
使用 DELETE 请求删除指定的文档。
示例:根据 ID 删除文档
DELETE /my_index/_doc/1
这将删除 my_index 索引库中 ID 为 1 的文档。如果指定的文档不存在,Elasticsearch 会返回一个 404 错误。
4. 总结
- 新增文档:
使用 POST /my_index/_doc/ 自动生成文档 ID 并添加文档。
使用 PUT /my_index/_doc/{id} 通过指定 ID 来新增或更新文档。 - 查询文档:
使用 GET /my_index/_doc/{id} 根据 ID 查询文档。
使用 GET /my_index/_search 执行复杂的搜索查询。 - 删除文档:使用 DELETE /my_index/_doc/{id} 根据 ID 删除文档。
6.2 修改文档
1.全量修改,删除旧文档,添加新文档
PUT /my_index/_doc/1
{
"title": "Updated Elasticsearch Basics",
"author": "John Doe",
"publish_date": "2024-01-01",
"price": 19.99
}
2.增量修改,修改指定字段值,使用 POST 和 _update API 进行部分更新。
示例:
POST /my_index/_doc/1/_update
{
"doc": {
"price": 24.99,
"title": "Elasticsearch Basics - Updated"
}
}
这里,doc 对象内的字段会被更新,而文档的其他字段保持不变。例如,price 和 title 字段会被更新为新的值,而其他字段(如 author、publish_date)将保持不变。
3. 通过脚本进行复杂的更新
示例:使用脚本增加字段值
POST /my_index/_doc/1/_update
{
"script": {
"source": "ctx._source.price += params.increment",
"lang": "painless",
"params": {
"increment": 5
}
}
}
- script:定义了更新操作的脚本。
source:指定实际执行的脚本代码,使用 painless 语言。
ctx._source.price 是指向文档中 price 字段的引用。 - lang:说明使用的脚本语言类型,这里使用 painless,它是 Elasticsearch 默认且推荐的脚本语言。
- params:传递给脚本的参数。这里 params 中定义了一个名为 increment 的参数,其值为 5
7 分词器
分词器(Tokenizer)是文本处理中的一个关键组件,尤其在搜索引擎、文本分析、自然语言处理(NLP)等领域中扮演重要角色。它的主要作用是将文本切分成若干个有意义的词或词组。分词器的使用可以帮助进行词频统计、信息检索、文本分类等任务。
7.1 分词器的基本概念
分词器的作用:
- 文本切分: 将长文本拆分成单独的词或词组。
- 标准化: 处理大小写、去除标点符号、转换数字等。
- 词汇建立: 建立词汇表以进行后续的分析。
常见的分词器类型:
- 基于规则的分词器: 使用预定义的规则进行分词。例如,使用空格、标点符号或特殊字符作为分隔符。
- 基于字典的分词器:使用词典或词汇表进行分词,例如,分词时根据字典中的词条进行匹配。
- 统计型分词器: 利用统计模型和算法进行分词,例如,基于频率的分词或机器学习模型。
7.2 Elasticsearch 分词器
Elasticsearch 是一个基于 Lucene 的分布式搜索引擎,它提供了多种分词器用于处理和分析文本数据。
- 标准分词器(Standard Tokenizer): 默认的分词器,适用于大多数语言。它基于 Unicode 字符集的标准分词算法。
- 空格分词器(Whitespace Tokenizer): 按照空格将文本分割成词,不处理其他字符。
- IK 分词器: 适用于中文分词,可以进行精确分词和智能分词。
- 自定义分词器: 用户可以根据需求自定义分词器,通过配置文件设置分词规则和词典。
7.3 IK分词器
IK 分词器是 Elasticsearch 中一个流行的中文分词器,适用于处理中文文本。
1. 安装 IK 分词器插件
2. 创建索引时使用 IK 分词器
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"ik_max_word": {
"type": "ik_max_word"
},
"ik_smart": {
"type": "ik_smart"
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
- ik_max_word:IK 分词器的最大词汇量分词模式,能将文本切分为尽可能多的词项。
- ik_smart:IK分词器的智能分词模式,切分出的词项数量较少,更加精准。
3. 使用 IK 分词器进行文档索引和查询
在创建了索引并配置了 IK 分词器之后,你可以像往常一样索引和查询文档。
POST /my_index/_doc/1
{
"content": "Elasticsearch 是一个分布式搜索引擎"
}
示例:搜索文档
json
复制代码
GET /my_index/_search
{
"query": {
"match": {
"content": "分布式搜索"
}
}
}
4. 测试 IK 分词器
使用 _analyze API 来测试 IK 分词器对文本的分词效果。
POST /my_index/_analyze
{
"analyzer": "ik_max_word",
"text": "Elasticsearch 是一个分布式搜索引擎"
}
- analyzer:指定你想要使用的 IK 分词器(如 ik_max_word 或 ik_smart)。
- text:输入的文本。
5. 扩展词库
6. 停用词库