从零开始的Elasticsearch学习-初步了解
一. Elastic Stack简介
Elastic Stack 是由 Elastic 公司开发的一套完整的开源日志和数据分析平台,它包括以下核心组件:
- Elasticsearch: 一个分布式、RESTful风格的搜索和数据分析引擎,能够实现实时的全文搜索、结构化搜索、数据分析以及对大规模数据的存储。
- Logstash: 一个服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,并将数据发送到您指定的存储库。
- Kibana: 一个开源的数据可视化界面,用于搜索、查看和交互存储在 Elasticsearch 索引中的数据。
- Beats: 轻量级的数据采集器,用于收集和转发数据给 Logstash、Elasticsearch 或其他存储和分析工具。
Elastic Stack 能够为日志、监控指标、交易数据等多种类型的数据提供强大的搜索、分析和可视化能力,广泛应用于日志分析、性能监控、内容搜索、安全情报等多个领域。
简单理解:可以简单认为elasticsearch是一个拥有强大搜索功能的数据库,像mysql一样提供了各种api(http请求,json格式传递数据),在没有使用es或其他搜索引擎的时候,我们需要从数据库搜索,在数据量比较大的时候,性能低,速度慢,elasticsearch是一个搜索运行速度快,零配置和完全免费的搜索引擎,我们可以把搜索功能交给它来处理
二. Elasticsearch中的基本概念
在深入了解 Elasticsearch 之前,我们需要掌握一些基本概念:
- 索引(Index): 索引是数据存储在 Elasticsearch 中的一个容器,类似于传统数据库中的数据库概念。每个索引都由一个或多个分片(Shard)组成,分片是物理或虚拟的机器上存储数据的容器。
- 文档(Document): 文档是索引中的基本数据单位,类似于传统数据库中的一条记录。每个文档都有一个唯一的标识符(ID),并且可以包含多个字段(Field),字段是文档中数据的最小单位。
- 字段(Field): 字段是文档中数据的最小单位,对应于传统数据库中的列。字段可以有不同的数据类型,如文本、数字、日期等。
- 文档类型(Document type):每个存储在索引(index)中的文档都有一个类型(type)和一个ID。需要注意的是,在Elasticsearch 7.x及以后的版本中,类型(type)的概念已经被移除,每个索引默认只有一个类型,即
_doc
- 分片(Shard): 为了分布式存储和提高性能,Elasticsearch 将索引分成多个分片。每个分片都是索引的一个独立副本,可以被分配到集群中的不同节点上。
- 节点(Node): 节点是运行 Elasticsearch 的服务器,可以承载一个或多个分片。节点可以是主节点、工作节点或协调节点,分别负责集群管理、数据操作和请求分发等任务。
- 集群(Cluster): 集群是由多个节点组成的一个 Elasticsearch 网络,所有节点共享相同的索引数据,并且可以协同工作以提供高可用性和扩展性。
与关系型数据库如mysql对照学习,Elasticsearch以JSON格式存储和接收数据,索引就像表,文档相当于表中一行数据,字段对应列
三. RESTful API
基本的CRUD 操作
-
创建(Create):
POST /index_name/_doc/id { "field1": "value1", "field2": "value2" }
此操作用于在指定索引(index_name)中创建一个新文档,并指定文档ID(id)。如果文档已存在,则会更新文档。
-
读取(Read):
GET /index_name/_doc/id
此操作用于获取指定索引中指定文档ID的文档内容。
-
更新(Update):
POST /index_name/_doc/id/_update { "doc": { "field1": "new_value1", "field2": "new_value2" } }
此操作用于更新指定索引中指定文档ID的文档内容。
-
删除(Delete):
DELETE /index_name/_doc/id
此操作用于删除指定索引中指定文档ID的文档。
创建和删除索引
-
创建索引:
PUT /index_name { "settings": { "number_of_shards": 3, "number_of_replicas": 2 }, "mappings": { "properties": { "field1": { "type": "text" }, "field2": { "type": "integer" } } } }
此操作用于创建一个新的索引(index_name),并设置分片数量(number_of_shards)和副本数量(number_of_replicas),同时定义索引的映射(mappings),即字段(field)和它们的数据类型(type)。
-
删除索引:
DELETE /index_name
此操作用于删除指定的索引。
搜索数据
DSL查询语句中包含多种查询子句,如“match”、“term”、“range”等,用于实现不同的搜索需求。例如,“match”子句用于全文搜索,“term”子句用于精确匹配,“range”子句用于范围搜索等。
- 关键字match查询
搜索名为“my_index”的索引中所有包含“apple”的文档:
GET /my_index/_search
{
"query": {
"match": {
"content": "apple"
}
}
}
这里,“content”是字段名,“apple”是要搜索的关键词。
- term聚合
term
查询用于精确匹配文档中的字段值。它不会像match对字段值进行分词处理,而是直接匹配整个值。这在字段值是关键词、枚举值或ID等固定值时非常有用。比如文章标题
以下是一个使用term
查询的DSL示例:
GET /my_index/_search
{
"query": {
"term": {
"status": {
"value": "active"
}
}
}
}
在这个例子中,我们搜索my_index
索引中status
字段值为active
的文档。注意,在term
查询中,需要使用value
关键字来指定要匹配的值。
- range聚合
range
聚合用于根据字段值的范围对数据进行分组。这对于分析数值字段或日期字段的分布情况非常有用。
以下是一个使用range
聚合的示例:
GET /sales/_search
{
"size": 0,
"aggs": {
"sales_ranges": {
"range": {
"field": "amount",
"ranges": [
{ "from": 0, "to": 100 },
{ "from": 100, "to": 500 },
{ "from": 500 }
]
}
}
}
}
在这个例子中,我们对sales
索引中的amount
字段进行了range
聚合。我们将销售额分为了三个范围:0到100,100到500,以及500以上。ranges
数组中的每个对象定义了一个范围,使用from
和to
关键字来指定范围的起始和结束值。注意,范围的结束值是开区间,即不包含该值。
另外,我们设置了size
为0,因为我们只关心聚合结果,而不关心具体的文档内容。
- 分页搜索
通过“size”参数限制返回的文档数量,通过“from”参数进行分页。
GET /my_index/_search
{
"query": {
"match": {
"content": "apple"
}
},
"size": 10,
"from": 0
}
- 排序和分组统计
以下是一个包含聚合和排序的DSL查询示例:
GET /my_index/_search
{
"query": {
"match": {
"content": "apple"
}
},
"aggs": {
"group_by_category": {
"terms": {
"field": "category.keyword"
}
}
},
"sort": [
{
"rating": {
"order": "desc"
}
}
]
}
这个查询将返回所有内容包含“apple”的文档,并按照“rating”字段降序排序。同时,还对搜索结果按照“category”字段进行分组统计。