Elasticsearch 是一个基于 Lucene 的开源分布式搜索引擎,可以用于全文搜索、结构化搜索和分析等应用领域。 它最初是由 Shay Banon 开发的在 Apache 开源许可证下发布。Elasticsearch 能够快速地将各种数据存储在多个节点的集群中,并且能够提供一个统一的接口进行检索和查询。
Elasticsearch 具有以下几个特点和优势:
在 Elasticsearch 中索引是指一个具有类型映射的容器,可以保存多个文档。 每个文档都有独立的 ID 以及相应的类型和属性。
索引可以被分成多个分片,每个分片可以分布在不同的节点上,这样就可以实现分布式存储和查询。分片有助于提高查询性能和吞吐量,并能够提高索引的可用性。
倒排索引是一种用于快速查找文档的数据结构,它将文档中的每个单词都映射到包含该单词的文档列表中,而不是像传统的索引那样将文档映射到单词列表中。 这样,在用户发起查询时,只需要在倒排索引表中查找包含所查询单词的文档列表,而不必扫描整个文档库,可以大大降低查询时的时间复杂度。
在 Elasticsearch 中倒排索引以一种高度压缩的方式存储。 它使用一种类似哈希表的数据结构,将单词与文档列表相关联,并将它们存储在硬盘上。每个文档 ID 都通过一个整型数字进行管理,这样可以提高查询的效率。 当用户发起一个查询时,Elasticsearch 会将查询语句转换为一组倒排索引表,并将它们作为输入传递给查询引擎,最终生成相关文档的排名列表,并返回给用户。
Lucene 是一个高性能、全文搜索引擎库,它提供了一组核心 API,可用于构建各种基于文本检索的应用。Lucene 同样也是由 Apache 开源的,被广泛地应用于多个领域,如搜索引擎、信息提取、文本挖掘等。Lucene 能够高效地创建和管理倒排索引,并且支持多种查询类型和过滤器。
Elasticsearch 基于 Lucene 构建而成,并且拥有 Lucene 的许多强大功能,如倒排索引和查询引擎等。 Elasticsearch 可以被看作是 Lucene 的一个扩展和增强,是一个更高级别的全文搜索和分析引擎。
Elaticsearch 是一款基于 Lucene 构建的搜索引擎,支持全文搜索、结构化搜索。以下是 Elasticsearch 的下载和安装步骤:
Elasticsearch 的默认配置可以满足大部分的需要,但在实际使用中,通常需要进行一些配置。以下是 Elasticsearch 一些常见的运行和配置:
network.host
配置项来修改绑定的 IP 地址。例如,network.host: 192.168.0.1
。discovery.seed_hosts
属性配置集群发现的 seed 集合,例如 discovery.seed_hosts: ["host1", "host2"]
。cluster.name
变量名来修改集群名称。Elasticsearch 支持多种数据导入方式,以下是一些常见的数据导入方式:
Elasticsearch 提供了许多 API 用于数据的操作和查询,以下是一些常见的操作和查询语法:
在解决海量数据存储和快速检索需求时,单个 Elasticsearch 节点已经不能满足需求了。以下是 Elasticsearch 集群搭建和配置的一些步骤:
node.name
和 network.host
和 http.port
三个参数。cluster.name
必须相同,并且将其他节点的 IP 地址添加到 discovery.seed_hosts
配置项中。良好的性能和操作可视化是保证 Elasticsearch 高效运行的关键。以下是一些 Elasticsearch 集群性能优化和监控工具:
Elasticsearch 是一款分布式搜索引擎,能够对数据进行全文检索、分析和存储。在搜索引擎中,Elasticsearch 可以被用于以下方面:
下面的 Java 代码实现基本的搜索功能
// 创建客户端连接
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
// 构建搜索请求
SearchRequest searchRequest = new SearchRequest("index_name");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("field", "keyword"));
searchRequest.source(searchSourceBuilder);
// 执行搜索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 处理搜索结果
for (SearchHit hit : searchResponse.getHits()) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
System.out.println(sourceAsMap.toString());
}
// 关闭客户端
client.close();
在日志分析场景中,Elasticsearch 可以使用 Logstash 和 Kibana 一起形成 ELK 技术栈,进行实时日志的收集、分析和展示。Elasticsearch 支持对大量的日志数据进行快速搜索和聚合。同时,Elasticsearch 还可以对日志数据进行定制化的监控和预警。
下面 Java 代码演示了如何使用 Logstash 将日志数据导入到 Elasticsearch 中
// 创建客户端连接
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
// 创建 Logstash 配置
String logstashConfig = "{\n" +
" \"input\": {\n" +
" \"file\": {\n" +
" \"path\": \"/path/to/logs\"\n" +
" }\n" +
" },\n" +
" \"output\": {\n" +
" \"elasticsearch\": {\n" +
" \"hosts\": [\"localhost:9200\"],\n" +
" \"index\": \"logs\"\n" +
" }\n" +
" }\n" +
"}";
// 构建请求
HttpEntity configEntity = new NStringEntity(logstashConfig, ContentType.APPLICATION_JSON);
Request request = new Request("PUT", "/_ingest/pipeline/logstash");
request.setEntity(configEntity);
// 执行请求
Response response = client.getLowLevelClient().performRequest(request);
// 处理结果
System.out.println(EntityUtils.toString(response.getEntity()));
// 关闭客户端
client.close();
在数据挖掘和统计分析场景中,Elasticsearch 可以使用聚合(aggregation)机制来实现多种统计分析任务。聚合是一种构建搜索管道的方式,类似于 SQL 中的 GROUP BY 语句。
下面Java 代码演示如何使用聚合来统计数据
// 创建客户端连接
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")
)
);
// 构建查询
SearchRequest searchRequest = new SearchRequest("index_name");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.aggregation(
AggregationBuilders.terms("my_term")
.field("my_field")
.subAggregation(
AggregationBuilders.avg("my_avg")
.field("my_value")
)
);
searchRequest.source(searchSourceBuilder);
// 执行查询
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 处理结果
Terms terms = searchResponse.getAggregations().get("my_term");
for (Terms.Bucket bucket : terms.getBuckets()) {
Aggregations subAggs = bucket.getAggregations();
Avg avg = subAggs.get("my_avg");
System.out.println(bucket.getKey() + " " + avg.getValue());
}
// 关闭客户端
client.close();