一. Elasticsearch 概述
Elasticsearch 的定义和背景
Elasticsearch是一个开源的分布式搜索和分析引擎,用于存储、搜索和分析大量的数据。它构建在Apache Lucene库之上,提供了简单易用的RESTful API和丰富的查询语言,使用户可以轻松地进行实时数据索引、搜索和分析。
Elasticsearch的背景可以追溯到2010年,由Elastic公司(前称为Elasticsearch BV)创立,旨在解决传统关系型数据库无法处理海量数据和实时搜索的问题。它最初是作为全文搜索引擎的扩展功能而开发的,并迅速发展成为一种强大的分布式数据存储和分析解决方案。
Elasticsearch采用分布式架构,可以将数据分散存储在多个节点上,以实现高可用性和扩展性。它使用倒排索引技术来加速搜索过程,通过将每个唯一词项与包含该词项的文档关联起来,快速定位相关文档。同时,Elasticsearch还支持复杂的查询和聚合操作,如全文搜索、地理空间搜索、过滤器、排序、分组和统计等,使用户能够灵活地进行数据分析和挖掘。
除了强大的搜索和分析功能,Elasticsearch还具有以下特点:
-
实时性: Elasticsearch可以在数据写入后几乎立即对其进行索引和搜索,支持实时数据分析和监控。
-
可扩展性: 用户可以轻松地水平扩展Elasticsearch集群,通过添加更多的节点来处理大规模数据和高并发请求。
-
多种数据类型支持: Elasticsearch可以处理各种类型的数据,包括结构化数据、半结构化数据和非结构化数据。
-
强大的查询语言: Elasticsearch提供了丰富的查询语言,如全文查询、词项查询、范围查询、布尔查询等,支持复杂的条件和聚合操作。
-
易于集成: Elasticsearch与许多常见的数据存储和处理工具集成紧密,如Logstash(数据收集和转换)、Beats(数据采集)、Kibana(数据可视化)等。
由于其出色的性能和灵活性,Elasticsearch已经广泛用于各种应用场景,包括日志分析、实时监控、企业搜索、电子商务、安全分析、数据挖掘等。它被许多大型企业和组织采用,并成为当前最受欢迎的开源搜索和分析引擎之一。
Elasticsearch 的主要用途和特点
主要用途:
-
搜索引擎:Elasticsearch提供强大的全文搜索功能,可以快速索引和搜索大量的结构化、半结构化和非结构化数据。它支持各种查询类型和复杂的搜索条件,满足实时搜索的需求。
-
日志和事件数据分析:Elasticsearch被广泛用于日志管理和分析。它能够接收和索引来自不同来源的日志数据,并支持实时的日志搜索和分析。通过使用Elastic Stack中的其他组件(如Logstash和Kibana),用户可以构建完整的日志分析解决方案。
-
实时监控和指标分析:Elasticsearch可以用于实时监控和分析系统的性能指标、日志和事件数据。它可以接收并索引来自多个来源的指标数据,并提供实时的仪表盘和可视化工具,帮助用户实时了解系统状态和性能。
-
企业搜索:Elasticsearch被广泛应用于企业搜索场景,如产品目录搜索、文档搜索和电子邮件搜索等。它可以处理大规模的文本数据集,并提供高效的全文搜索、自动完成和相关性排序等功能。
-
数据分析和挖掘:Elasticsearch支持各种聚合操作,如统计、分组、排序和桶分析等。这使得用户可以从大规模数据集中提取有价值的信息,进行深入的数据分析和挖掘。
主要特点:
-
分布式架构:Elasticsearch采用分布式架构,可以处理大规模数据和高并发请求。它将数据分散存储在多个节点上,并提供数据冗余备份,以实现高可用性和扩展性。
-
实时性:Elasticsearch支持实时索引和查询数据,可以几乎立即对写入的数据进行索引和搜索。这使得用户可以快速获得最新的数据结果,并进行实时监控和决策。
-
强大的查询语言:Elasticsearch提供丰富的查询语言,包括全文查询、词项查询、范围查询、布尔查询等。用户可以通过灵活的查询条件和过滤器来获取精确的搜索结果。
-
多样化的数据类型支持:Elasticsearch可以处理各种类型的数据,包括结构化数据、半结构化数据和非结构化数据。它能够自动推断字段类型,并提供相应的索引和搜索功能。
-
易于集成和扩展:Elasticsearch与许多常见的数据存储和处理工具紧密集成,如Logstash、Beats和Kibana。它还提供了灵活的RESTful API,方便与其他应用程序进行集成和扩展。
-
开源和活跃的社区支持:Elasticsearch是一个开源项目,拥有庞大的开发者社区。这意味着用户可以从社区中获取丰富的资源、文档和支持,并参与到项目的发展和改进中。
二. 基本概念和核心组件
索引、文档、类型等基础概念
-
索引(Index):
- 索引是 Elasticsearch 中最顶层的数据容器,用于组织和存储相关的文档。
- 索引由一个或多个分片(Shard)组成,每个分片是一组独立的文档集合。
- 每个索引都有一个唯一的名称,用于在搜索和操作过程中引用它。
操作演示:
- 创建一个名为 “my-index” 的索引:
PUT /my-index
-
文档(Document):
- 文档是 Elasticsearch 中的基本数据单元,以 JSON 格式表示,类似于传统数据库中的行。
- 文档是与索引相关联的实际数据,可以是任何形式的信息。
- 每个文档都有一个唯一的 ID 来标识自己,并属于特定的索引。
操作演示:
- 在 “my-index” 索引中创建一个 ID 为 “1” 的文档:
POST /my-index/_doc/1 {"title": "Elasticsearch 介绍","content": "Elasticsearch 是一个开源的分布式搜索引擎,用于高效地存储、检索和分析数据。","timestamp": "2023-06-29T00:00:00" }
-
类型(Type):
- 在 Elasticsearch 7.x 版本之前,一个索引可以包含多个类型。类型是索引内部的逻辑分类,用于将文档按照某种方式分组。
- 每个类型都有自己的映射(Mapping),它定义了每个字段的数据类型、分析器和其他属性。
操作演示:
-
创建一个名为 “my-index” 的索引,并定义一个名为 “product” 的类型:
PUT /my-index {"mappings": {"product": {"properties": {"name": { "type": "text" },"price": { "type": "float" }}}} }
-
在 “my-index” 索引的 “product” 类型中创建一个名为 “1” 的文档:
PUT /my-index/product/1 {"name": "iPhone","price": 999.99 }
从 Elasticsearch 7.x 版本开始,类型逐渐被废弃,推荐将数据以更细粒度的索引方式进行组织。
集群、节点和分片的概念及其作用
-
Elasticsearch 集群:
- Elasticsearch 集群是由一个或多个节点组成的集合。它具有分布式特性,可以将数据分布在多个节点上,从而实现高可用性和扩展性。
- 集群中的每个节点都知道整个集群的状态,并可以接收和处理请求。节点之间通过内部通信来协调数据的分布和复制。
-
Elasticsearch 节点:
- 节点是构成 Elasticsearch 集群的基本单元。一个节点可以是一台物理服务器或虚拟机。
- 在集群中,每个节点都有一个唯一的名称,并且扮演着特定的角色,如主节点、数据节点或协调节点等。
- 主节点负责集群级别的管理和维护,协调节点负责请求路由,而数据节点存储和处理数据。
-
Elasticsearch 分片:
- 分片是索引中数据的逻辑划分单元。每个索引可以被分成多个分片,分布在集群中的不同节点上。
- 分片是 Elasticsearch 实现高扩展性和水平分布式存储的关键。它允许数据在集群中分布存储,并提供并行处理能力。
- 每个分片本身就是一个完整的、独立的索引,具有自己的倒排索引、文档和对应的搜索服务。
分片包括两种类型:
- 主分片(Primary Shard):每个文档都被分配到一个主分片上,主分片负责文档的增删改操作。
- 副本分片(Replica Shard):主分片的副本,用于提供冗余和高可用性。副本分片负责读操作,可以在主分片不可用时接管。
注意事项:
- 分片的数量在索引创建时定义,并且一旦创建后不能更改。
- 在决定分片数量时,需要考虑集群的大小、硬件资源以及数据量等因素。
主分片和副本分片的使用和配置方法
-
主分片(Primary Shard):
- 主分片负责索引中文档的增删改操作。
- 每个文档都会被分配到一个主分片上,主分片根据文档的 ID 进行哈希计算,并将文档存储在相应的主分片上。
- 索引中的每个主分片都是一个独立的、完整的 Lucene 索引。
配置方法:
- 在创建索引时,可以通过设置参数
"number_of_shards"
来定义主分片的数量。 - 例如,创建一个具有 5 个主分片的索引:
PUT /my-index {"settings": {"number_of_shards": 5},"mappings": {...} }
-
副本分片(Replica Shard):
- 副本分片是主分片的复制品,用于提供冗余和高可用性。副本分片也可以处理读操作,以支持更好的并发性和负载均衡。
- 当主分片不可用时,副本分片可以接替成为新的主分片,并确保数据的可访问性和持久性。
- 副本分片还允许在集群中的多个节点上并行地处理搜索请求。
配置方法:
-
在创建索引时,可以通过设置参数
"number_of_replicas"
来定义副本分片的数量。 -
例如,创建一个具有 1 个副本分片的索引:
PUT /my-index {"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {...} }
-
可以动态调整索引的副本分片数量。例如,将索引的副本分片数量增加到 2:
PUT /my-index/_settings {"index": {"number_of_replicas": 2} }
主分片和副本分片在 Elasticsearch 中起到不同的作用。主分片负责索引的写操作,而副本分片提供冗余、高可用性和读操作的支持。您可以在索引创建或动态修改过程中设置主分片和副本分片的数量,以满足您的需求。
三、搜索
搜索的基本原理
Elasticsearch 是将搜索请求发送到整个集群中的各个节点,并通过倒排索引来快速找到匹配的文档。
-
倒排索引(Inverted Index):
- Elasticsearch 使用倒排索引来加速搜索。倒排索引是一个将每个词与包含该词的文档关联起来的数据结构。
- 它是通过将文档中的每个词抽取出来,然后记录该词出现在哪些文档中来构建的。
- 以词为基础构建索引,而不是以文档为基础进行搜索,这使得 Elasticsearch 可以在大量文档中进行高效的全文搜索。
-
分词器(Tokenizer)和分析器(Analyzer):
- 在构建倒排索引之前,Elasticsearch 使用分词器对文本进行处理,将其切分成一个个的词(term)。
- 分析器是由分词器、字符过滤器和标记过滤器组成的一个处理链。
- 分词器将文本切分成单个的词,字符过滤器对词进行预处理(如去除标点符号、转换大小写等),标记过滤器对词进行进一步处理(如同义词替换、词干提取等)。
-
查询解析和查询语句:
- 在搜索请求中,Elasticsearch 接收到查询字符串并进行解析。
- Elasticsearch 支持多种类型的查询,如全文查询、精确值查询、范围查询等。
- 查询解析过程将查询字符串转换为内部的查询对象,然后与倒排索引进行匹配。
-
倒排索引的匹配和评分:
- 当查询被解析后,Elasticsearch 将查询与倒排索引进行匹配。
- 倒排索引会快速找到包含查询中的词的文档,并生成初始的匹配结果集。
- 这些匹配结果都带有分数(score),用于衡量文档与查询的相关性。
-
结果排序和高亮显示:
- Elasticsearch 可以根据匹配文档的相关性对搜索结果进行排序。
- 通过给每个文档计算一个得分来提供排序依据,得分通常基于词频、字段长度、查询权重等因素。
- 此外,Elasticsearch 还支持在搜索结果中高亮显示查询的关键字,以便更好地展示匹配部分。
-
分布式搜索:
- Elasticsearch 是一个分布式搜索引擎,可以水平扩展以处理大规模数据。
- 当进行搜索时,查询将被分发到整个集群中的各个节点,并行地执行查询操作。
- 每个节点在本地返回局部的匹配结果,然后由协调节点(coordinator)将这些结果进行合并和排序,最后返回给用户。
Elasticsearch 能够快速而高效地进行全文搜索,并提供准确的搜索结果。对于大规模和复杂的数据集,它的搜索能力得到了有效的优化和扩展。
如何构建查询语句
构建查询语句是使用 Elasticsearch 进行搜索的关键步骤之一。通过构建准确和灵活的查询语句,可以获得符合需求的搜索结果。
-
查询类型选择:
- Elasticsearch 提供了多种查询类型,例如全文查询、精确值查询、范围查询等。根据需求选择合适的查询类型。
-
构建查询条件:
- 查询条件是指要在搜索中匹配的规则和限制。它们由 JSON 组成,可以包含多个字段和操作符。
- 常见的字段包括索引、类型、文档属性和字段等。操作符用于确定搜索的逻辑关系,如匹配、不匹配、范围等。
-
使用查询字符串(Query String):
- Elasticsearch 提供了一种简化的查询方式,即查询字符串。它允许您以人类可读的方式构建查询,而不需要编写复杂的 JSON 查询语句。
- 查询字符串可以包含字段名、关键词、布尔运算符和通配符等。
-
使用 Query DSL:
- 如果需要更复杂和灵活的查询,可以使用 Elasticsearch 的 Query DSL(Domain Specific Language)。
- Query DSL 是 Elasticsearch 提供的一种强大而灵活的查询语法,可以根据具体需求构建复杂的查询结构。
- Query DSL 使用 JSON 对象来表示查询,可以包含各种查询类型、过滤器、聚合等。
-
添加过滤器(Filters):
- 过滤器用于进一步限制搜索结果,以筛选出满足特定条件的文档。
- 过滤器可以与查询结合使用,也可以单独使用。它们可以根据字段的值进行匹配或排除。
-
使用聚合(Aggregations):
- Elasticsearch 的聚合功能可以对搜索结果进行分组、统计和计算。
- 通过聚合,可以获得关于数据集的更深入的洞察,并生成各种统计指标,如平均值、最大值、最小值等。
-
调整查询参数:
- Elasticsearch 允许您调整查询的各种参数,以控制搜索的行为和性能。
- 例如,您可以设置返回结果的数量、排序规则、分页设置、超时时间等。
示例
-
全文查询(Match Query):
- 查询特定字段中包含指定关键词的文档。
{"query": {"match": {"title": "Elasticsearch"}} }
-
精确值查询(Term Query):
- 查询特定字段中精确匹配指定值的文档。
{"query": {"term": {"category": "Technology"}} }
-
范围查询(Range Query):
- 查询特定字段中落在指定范围内的文档。
{"query": {"range": {"price": {"gte": 10,"lte": 100}}} }
-
布尔查询(Bool Query):
- 组合多个子查询条件,使用逻辑运算符进行匹配。
{"query": {"bool": {"must": [{ "match": { "title": "Elasticsearch" } },{ "term": { "category": "Technology" } }],"must_not": { "term": { "status": "Archived" } }}} }
-
高亮显示查询结果:
- 在查询结果中高亮显示匹配的关键词。
{"query": {"match": {"content": "Elasticsearch"}},"highlight": {"fields": {"content": {}}} }
使用过滤器和聚合操作进行高级搜索
使用过滤器和聚合操作是进行高级搜索的重要手段。过滤器用于筛选搜索结果,而聚合操作用于分组、统计和计算搜索结果。
-
过滤器(Filters):
- 过滤器用于根据特定条件来筛选文档,只返回满足条件的文档,而不会对得分进行影响。
- 过滤器可以与查询结合使用,也可以单独使用。
- 常见的过滤器类型包括:
- Term Filter:匹配指定字段中精确匹配的值。
- Range Filter:匹配指定字段中落在指定范围内的值。
- Exists Filter:匹配指定字段存在的文档。
- Bool Filter:根据多个子过滤器的逻辑关系进行匹配。
- Geo Distance Filter:匹配指定字段中距离某一地理点一定范围内的值。
-
聚合操作(Aggregations):
- 聚合操作用于在搜索结果上进行分组、统计和计算,从而获取更深入的洞察和统计指标。
- 聚合操作基于搜索结果集进行操作,并返回计算后的结果。
- 常见的聚合操作类型包括:
- Terms Aggregation:根据指定字段的值进行分组,并统计每个分组的文档数或其他指标。
- Range Aggregation:将指定字段的值划分为多个范围,并统计落在每个范围内的文档数或其他指标。
- Date Histogram Aggregation:按照时间间隔对指定字段进行分组,并统计每个时间间隔内的文档数或其他指标。
- Avg/Min/Max/Sum Aggregation:计算指定字段的平均值、最小值、最大值、总和等统计指标。
- Nested/Reverse Nested Aggregation:用于处理嵌套的文档结构,并对嵌套字段进行聚合操作。
通过使用过滤器和聚合操作,可以实现更精确的搜索和更深入的数据分析。可以根据具体需求来选择合适的过滤器类型和聚合操作,并根据数据结构和索引映射来构建高级搜索查询语句。
示例
- 过滤器示例:
假设我们有一个电商平台的商品索引,每个商品文档包含字段:title
(商品标题)、price
(价格)和category
(商品类别)。我们想要查询价格在 10 到 100 之间,并且类别为 “Technology” 的商品。
{"query": {"bool": {"filter": [{"range": {"price": {"gte": 10,"lte": 100}}},{"term": {"category": "Technology"}}]}}
}
在上述查询中,我们使用了 Bool 查询构造器来组合多个过滤器。range
过滤器用于筛选价格在指定范围内的商品,而 term
过滤器则用于筛选类别为 “Technology” 的商品。该查询返回的结果将只包含满足这两个条件的商品文档。
- 聚合操作示例:
继续沿用上述的电商平台商品索引示例,现在我们想要统计不同类别的商品数量,并按照数量从高到低进行排序。
{"aggs": {"category_count": {"terms": {"field": "category","size": 10,"order": {"_count": "desc"}}}}
}
在上述聚合操作中,我们使用了 Terms 聚合操作来按照 category
字段对商品进行分组,并计算每个分类的文档数量。size
参数指定了返回的分组数量上限,而 order
参数以文档数量 _count
字段的降序进行排序。该查询将返回按照商品类别分组后的结果,其中每个分组都包含类别和对应的商品数量。
四、映射和分析
映射的概念和作用
在 Elasticsearch 中,映射(Mapping)是用于定义文档如何存储和索引的过程。它决定了文档中的字段及其属性,例如数据类型、分词器、索引设置等。映射在建立索引之前定义,并且在索引过程中将其应用于文档,以便 Elasticsearch 能够正确地解析和处理文档的内容。
映射的作用包括:
-
定义字段类型:
- 映射确定每个字段的数据类型,如字符串、数字、日期等。这对于搜索和排序是非常重要的,因为不同的数据类型具有不同的排序和比较方式。
- 例如,一个字段可以定义为
text
类型,用于全文搜索,或者定义为keyword
类型,用于精确匹配和聚合操作。
-
配置分词器:
- 映射通过指定分词器来定义文本字段的文本处理方式,将文本拆分成独立的单词(术语)。
- 分词器用于构建倒排索引,使得可以根据单词进行搜索,并实现全文搜索的功能。
- 例如,可以为英文字段指定
standard
分词器,而为中文字段指定smartcn
分词器。
-
索引控制:
- 映射还允许配置字段是否需要被索引以及如何被索引。
- 可以指定字段是否需要被全文索引(用于全文搜索)或者只需要被精确匹配索引(用于过滤器和聚合操作)。
- 还可以配置索引设置,如分片数、副本数、刷新频率等。
-
动态映射:
- Elasticsearch 支持自动检测并根据新文档的字段自动生成映射。这称为动态映射。
- 动态映射根据字段值自动推断数据类型,并为其创建默认映射。
- 可以通过预定义映射和显式映射来控制动态映射的行为,以确保正确的字段类型和属性被应用。
通过映射,我们可以灵活地定义文档结构和字段属性,以满足特定的搜索和分析需求。良好的映射设计可以提高搜索性能、减少存储空间,并确保数据的一致性和准确性。在建立索引之前,仔细考虑和定义映射是非常重要的。
示例
以下是一个示例,展示了如何定义一个映射来索引包含不同类型字段的文档:
PUT /my_index
{"mappings": {"properties": {"title": {"type": "text"},"price": {"type": "float"},"category": {"type": "keyword"},"description": {"type": "text","analyzer": "english"},"created_at": {"type": "date","format": "yyyy-MM-dd HH:mm:ss"}}}
}
在上述示例中:
- 我们创建了一个名为
my_index
的索引,并指定了其映射。 properties
对象用于定义索引中的字段和其属性。title
字段被定义为text
类型,可以用于全文搜索。price
字段被定义为float
类型,可以用于数值排序和统计。category
字段被定义为keyword
类型,用于精确匹配和聚合操作。description
字段被定义为text
类型,并指定了分词器english
,用于英文文本的处理。created_at
字段被定义为date
类型,并指定了日期格式。
通过这样的映射定义,当我们索引文档时,Elasticsearch 将根据映射来解析和处理各个字段的内容,并构建适合搜索和分析的倒排索引结构。这使得我们可以使用各种查询和聚合操作来搜索、过滤和分析文档中的数据。
使用分析器进行文本处理和搜索优化
使用分析器是 Elasticsearch 中进行文本处理和搜索优化的关键步骤之一。分析器负责将文本转换为有意义的词条,以便能够进行有效的搜索和分析。
-
了解分析器的类型:
Elasticsearch 提供了多种类型的分析器,每个分析器都有不同的用途和效果。- 标准分析器(Standard Analyzer):默认的分析器,适用于大多数场景,包括分割文本、删除停用词、小写化等。
- 简单分析器(Simple Analyzer):根据非字母字符进行简单分割,不考虑大小写或停用词。
- 语言分析器(Language Analyzer):针对特定语言设计的分析器,例如英语分析器(English Analyzer)或中文分析器(Chinese Analyzer)等。
- 自定义分析器(Custom Analyzer):允许你根据具体需求自定义分析器的组合,可以包含多个分词器、过滤器等。
-
创建索引时定义分析器:
在创建索引时,可以通过指定mappings
字段来定义分析器。在字段的映射中,使用analyzer
属性来指定要使用的分析器。{"mappings": {"properties": {"field_name": {"type": "text","analyzer": "analyzer_name"},...}} }
field_name
:要应用分析器的字段名称。type
:字段类型,通常为text
。analyzer_name
:要使用的分析器的名称。
-
动态映射和自动应用分析器:
默认情况下,Elasticsearch 在创建索引时会根据字段的数据类型自动应用相应的分析器。例如,对于text
类型的字段,将自动应用默认的标准分析器。这是通过动态映射实现的。 -
明确指定分析器:
如果你想显式地指定要使用的分析器,可以在查询或索引文档时使用_analyze
API 来手动应用分析器。GET /my_index/_analyze {"analyzer": "analyzer_name","text": "your_text_to_analyze" }
analyzer_name
:要使用的分析器的名称。your_text_to_analyze
:要进行分析的文本。
-
分词器和过滤器:
分析器由分词器(Tokenizer)和过滤器(Filter)组成。分词器负责将文本拆分成单独的词条,而过滤器则对词条进行进一步的处理,如删除停用词、词干提取、大小写转换等。 -
自定义分析器:
如果预定义的分析器无法满足特定需求,你可以构建自定义分析器。自定义分析器可以包含一个或多个分词器和过滤器,以便根据需要进行文本处理。 -
查看分析结果:
在使用分析器时,你可以使用_analyze
API 来查看分析结果,以确保分析器正常工作并生成预期的词条。 -
更新分析器:
如果已经创建了索引,但想要更改字段的分析器,需要重新创建索引或使用 Elasticsearch 的 Reindex API 将文档从旧索引重新索引到新索引中。
通过使用适当的分析器和配置,可以实现更好的搜索效果和更准确的文本分析。请根据具体需求选择合适的分析器,并确保对分析结果进行验证和测试。
示例
假设我们有一个索引,用于存储产品信息,并且想要对产品的描述字段进行文本处理和搜索优化。我们将使用标准分析器来演示。
-
创建索引时定义分析器:
我们可以在创建索引时为描述字段指定使用的分析器。PUT /products {"settings": {"analysis": {"analyzer": {"my_analyzer": {"type": "standard"}}}},"mappings": {"properties": {"description": {"type": "text","analyzer": "my_analyzer"}}} }
在上述示例中,我们定义了一个名为
my_analyzer
的标准分析器,并将其应用于description
字段。 -
插入文档:
现在,我们可以插入一些文档到products
索引中,包含产品的描述信息。POST /products/_doc/1 {"description": "这是一个高质量的耳机,具有优秀的音质和舒适的佩戴体验。" }POST /products/_doc/2 {"description": "这款电视屏幕尺寸大,画质清晰逼真,适合观看电影和玩游戏。" }
-
搜索文档:
现在,我们可以使用搜索查询来搜索具有特定关键字的产品描述。GET /products/_search {"query": {"match": {"description": "电视"}} }
上述搜索查询将返回含有关键字 “电视” 的产品描述。
五、监控和日志
使用集群健康 API 监控集群状态
-
API名称和端点:
- API名称:集群健康API(Cluster Health API)
- 端点:/_cluster/health
-
请求方法:
- GET方法
-
请求参数:
- level(可选):指定返回的健康级别,可以是下列之一:
- cluster:返回整个集群的健康信息(默认)
- indices:返回每个索引的健康信息
- shards:返回每个分片的健康信息
- wait_for_status(可选):等待集群达到指定状态后再返回响应,默认为green。可选的状态有:
- green:所有主分片和副本分片都可用
- yellow:所有主分片可用,但不是所有副本分片都可用
- red:至少有一个主分片不可用
- timeout(可选):设置等待状态的超时时间,默认为30秒。
- master_timeout(可选):等待选择主节点的超时时间,默认为30秒。
- level(可选):指定返回的健康级别,可以是下列之一:
-
响应结果:
- cluster_name:集群名称
- status:集群健康状态,可能的值有:
- green:所有主分片和副本分片都可用
- yellow:所有主分片可用,但不是所有副本分片都可用
- red:至少有一个主分片不可用
- timed_out:请求是否超时
- number_of_nodes:集群中节点的数量
- number_of_data_nodes:数据节点的数量
- active_primary_shards:活动的主分片数量
- active_shards:活动的分片数量(包括主分片和副本分片)
- relocating_shards:正在迁移的分片数量
- initializing_shards:正在初始化的分片数量
- unassigned_shards:未分配的分片数量
- delayed_unassigned_shards:延迟未分配的分片数量
- number_of_pending_tasks:待处理的任务数量
- number_of_in_flight_fetch:正在进行的取回操作数量
- task_max_waiting_in_queue_millis:在队列中等待的最长任务时间(毫秒)
- active_shards_percent_as_number:以百分比形式表示的活动分片比例
-
示例请求和响应:
- 请求示例:GET /_cluster/health?level=indices
- 响应示例:
{"cluster_name": "my_cluster","status": "green","timed_out": false,"number_of_nodes": 5,"number_of_data_nodes": 3,"active_primary_shards": 10,"active_shards": 20,"relocating_shards": 0,"initializing_shards": 0,"unassigned_shards": 0,"delayed_unassigned_shards": 0,"number_of_pending_tasks": 0,"number_of_in_flight_fetch": 0,"task_max_waiting_in_queue_millis": 0,"active_shards_percent_as_number": 100.0 }
通过使用集群健康API,您可以定期调用该API以获取关于集群的实时状态信息。这有助于监控集群运行状况、检测潜在问题并及时采取行动。您还可以基于集群健康的状态定义警报规则,以便在集群出现问题时及时通知负责人员。
配置和查看日志文件
-
配置日志文件:
要配置日志文件,需要修改Elasticsearch的配置文件,该文件位于config
目录下。默认情况下,配置文件名为elasticsearch.yml
。- 打开配置文件:使用文本编辑器打开
elasticsearch.yml
文件。 - 配置日志级别:找到日志级别配置项,默认为
info
,可以根据需要更改为debug
、warn
或error
等级别。 - 配置日志输出位置:找到
path.logs
配置项,设置日志文件的输出路径。可以指定完整路径,或者使用相对于ES_HOME
(Elasticsearch安装目录)的路径。
- 打开配置文件:使用文本编辑器打开
-
查看日志文件:
日志文件位于指定的输出路径,默认为logs
目录。您可以通过以下方式查看日志文件:- 使用命令行:在命令行中使用文本查看工具(如
cat
、tail
等)来查看日志文件,例如:cat path/to/logfile.log
。 - 使用图形界面工具:使用文件管理器或文本编辑器,打开日志文件查看其内容。
- 使用命令行:在命令行中使用文本查看工具(如
-
日志文件的类型:
Elasticsearch生成多个日志文件,其中包括:- elasticsearch.log:主要日志文件,包含Elasticsearch的运行状态、异常和操作相关的信息。
- gc.log:GC(垃圾回收)日志文件,记录了JVM的垃圾回收活动。
- deprecation.log:包含关于使用已弃用功能的警告信息。
- audit.log:若启用了审计功能,将记录审核事件的日志。
-
日志文件的轮转和归档:
Elasticsearch支持日志文件的轮转和归档,以便管理和维护日志文件的大小和数量。可以使用第三方的日志轮转工具(如logrotate
)来完成此任务,并在配置文件中指定轮转的规则和频率。例如,使用
logrotate
工具,在/etc/logrotate.d
目录下创建一个名为elasticsearch
的配置文件,并添加以下内容:/path/to/elasticsearch/logs/*.log {dailyrotate 7compressdelaycompressmissingoknotifempty }
这将每天轮转一次日志文件,并保留最近的7个归档文件。
通过配置和查看日志文件,您可以及时获取Elasticsearch集群的运行状态、故障信息和性能问题,有助于排查和解决各种问题,并确保集群的顺利运行。
六、实际应用
电商平台的商品搜索和推荐
假设我们有一个电商平台,用户可以通过搜索框来搜索商品,并根据他们的行为历史和喜好,我们也希望能够向他们推荐相关的商品。
步骤1: 数据准备
首先,我们需要准备商品数据。假设我们有以下三个商品的数据:
- 商品1:
- 名称:iPhone 12
- 描述:Apple 最新款智能手机
- 价格:9999元
- 品牌:Apple
- 类别:手机
- 商品2:
- 名称:Samsung Galaxy S21
- 描述:三星旗舰智能手机
- 价格:8999元
- 品牌:Samsung
- 类别:手机
- 商品3:
- 名称:Sony WH-1000XM4
- 描述:无线降噪耳机
- 价格:1999元
- 品牌:Sony
- 类别:耳机
步骤2: 索引和映射设置
接下来,我们需要创建一个索引,并定义映射设置,以便Elasticsearch知道如何处理我们的商品数据。我们将使用Elasticsearch的Index API和Mapping API来完成这一步。
下面是一个使用CURL命令创建索引和定义映射的示例:
PUT /products
{"mappings": {"properties": {"name": {"type": "text"},"description": {"type": "text"},"price": {"type": "float"},"brand": {"type": "keyword"},"category": {"type": "keyword"}}}
}
在上述示例中,我们使用PUT请求创建了一个名为"products"的索引,并指定了每个字段的数据类型。
步骤3: 数据导入
接下来,我们将商品数据导入到Elasticsearch索引中。我们可以使用Elasticsearch的Index API来完成这一步。
下面是一个使用CURL命令将每个商品文档导入到"products"索引的示例:
POST /products/_doc/1
{"name": "iPhone 12","description": "Apple 最新款智能手机","price": 9999,"brand": "Apple","category": "手机"
}POST /products/_doc/2
{"name": "Samsung Galaxy S21","description": "三星旗舰智能手机","price": 8999,"brand": "Samsung","category": "手机"
}POST /products/_doc/3
{"name": "Sony WH-1000XM4","description": "无线降噪耳机","price": 1999,"brand": "Sony","category": "耳机"
}
在上述示例中,我们使用POST请求将每个商品文档导入到"products"索引中,每个文档都有一个唯一的标识符(例如1、2、3)。
步骤4: 商品搜索接口
现在,我们准备好进行商品搜索。我们将使用Elasticsearch的Search API来执行搜索请求。
下面是一个使用CURL命令进行商品搜索的示例:
GET /products/_search
{"query": {"match": {"name": "iphone"}}
}
在上述示例中,我们使用GET请求执行了一个商品搜索请求,查询包含"iphone"关键字的商品名称。
步骤5: 查询构建和商品搜索
接下来,让我们使用Java代码来构建并执行相同的商品搜索请求。我们将使用Elasticsearch的Java High-Level REST Client来实现。
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;import java.io.IOException;public class ElasticsearchProductSearchExample {private static final String INDEX_NAME = "products";private static final String HOSTNAME = "localhost";private static final int PORT_NUMBER = 9200;public static void main(String[] args) {RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(HOSTNAME, PORT_NUMBER, "http")));try {// 构建商品搜索请求SearchRequest searchRequest = new SearchRequest(INDEX_NAME);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", "iphone");searchSourceBuilder.query(matchQuery);searchRequest.source(searchSourceBuilder);// 执行商品搜索请求SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);// 处理商品搜索结果searchResponse.getHits().forEach(hit -> {System.out.println(hit.getSourceAsString());});} catch (IOException e) {e.printStackTrace();} finally {try {client.close();} catch (IOException e) {e.printStackTrace();}}}
}
在上述Java代码示例中,我们创建了一个RestHighLevelClient
实例,并指定Elasticsearch主机的主机名和端口号。
我们使用SearchRequest
和SearchSourceBuilder
来构建商品搜索请求。在商品搜索请求中,我们使用MatchQueryBuilder
指定查询关键字并设置要在哪个字段上执行。
使用client.search
方法来执行商品搜索请求,并使用SearchResponse
处理搜索结果。
步骤6: 商品推荐接口
除了商品搜索,我们还希望能够向用户推荐相关的商品。为此,我们可以使用Elasticsearch的推荐功能。具体来说,我们可以使用基于用户历史行为的协同过滤推荐算法来推荐商品。
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;import java.io.IOException;public class ElasticsearchProductRecommendationExample {private static final String INDEX_NAME = "products";private static final String HOSTNAME = "localhost";private static final int PORT_NUMBER = 9200;public static void main(String[] args) {RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(HOSTNAME, PORT_NUMBER, "http")));try {// 构建商品推荐请求SearchRequest searchRequest = new SearchRequest(INDEX_NAME);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("category", "手机");searchSourceBuilder.query(matchQuery);searchSourceBuilder.size(5); // 限制结果数量为5个searchRequest.source(searchSourceBuilder);// 执行商品推荐请求SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);// 处理商品推荐结果searchResponse.getHits().forEach(hit -> {System.out.println(hit.getSourceAsString());});} catch (IOException e) {e.printStackTrace();} finally {try {client.close();} catch (IOException e) {e.printStackTrace();}}}
}
在上述Java代码示例中,我们使用相同的步骤来创建和关闭RestHighLevelClient
实例。
我们使用SearchRequest
和SearchSourceBuilder
来构建商品推荐请求。在商品推荐请求中,我们使用MatchQueryBuilder
指定查询的条件(例如商品类别为手机)。
此外,我们可以使用searchSourceBuilder.size
方法限制结果数量,以便只返回若干个推荐商品。
使用client.search
方法来执行商品推荐请求,并使用SearchResponse
处理搜索结果。