ElasticSearch 优点及与spring boot 结合 完整代码
Elasticsearch 是一个基于 Apache Lucene 构建的开源搜索引擎,
优点:
-
全文搜索能力: Elasticsearch 提供了强大的全文搜索功能,支持多种语言,能够高效地执行复杂的文本查询。
-
分布式架构: Elasticsearch 本质上是分布式的,支持跨多个节点的数据分片(Sharding)和复制(Replication),这提高了系统的可扩展性和可靠性。
-
实时搜索: Elasticsearch 能够提供近乎实时的搜索体验,索引更新和搜索几乎可以同时进行。
-
高可用性和可扩展性: 通过简单地增加节点,Elasticsearch 可以水平扩展以处理更多的数据和查询负载,同时保持高可用性。
-
多样的客户端接口: Elasticsearch 提供了丰富的 RESTful API 接口,可以使用多种编程语言轻松集成和交互。
-
强大的分析能力: Elasticsearch 不仅仅是搜索引擎,还提供了强大的数据聚合功能,可以用于复杂的数据分析和可视化。
-
丰富的生态系统: Elasticsearch 是 Elastic Stack 的一部分,与 Logstash(数据处理工具)和 Kibana(数据可视化工具)紧密集成,为日志分析、监控、全文搜索等提供了完整的解决方案。
-
易于监控和管理: Elasticsearch 提供了多种监控和管理工具,如 Elastic Stack 的 X-Pack 插件,提供安全、监控、报告等高级功能。
-
灵活的数据模型: Elasticsearch 使用 JSON 作为文档格式,这使得它可以轻松地处理复杂的、多层次的数据结构。
-
强大的查询DSL: Elasticsearch 的查询DSL(Domain Specific Language)非常灵活和强大,支持从简单的文本查询到复杂的聚合和脚本查询。
-
社区支持: 作为一个受欢迎的开源项目,Elasticsearch 拥有一个活跃的社区,可以提供丰富的资源、插件和支持。
-
场景适用性广: Elasticsearch 被广泛应用于日志收集与分析、网站搜索、企业搜索、安全信息和事件管理(SIEM)、机器学习等多种场景。
这些优点使得Elasticsearch成为了许多公司和开发者选择的搜索引擎和数据分析工具。
实战:
要在 Spring Boot 应用程序中集成 Elasticsearch,你需要添加相关的依赖、配置 Elasticsearch 客户端,并创建对应的实体、仓库接口等。以下是一个简单的示例,展示了如何在 Spring Boot 应用程序中使用 Elasticsearch。
首先,添加 Spring Data Elasticsearch 的依赖到你的 pom.xml
文件中:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Other dependencies -->
</dependencies>
配置 Elasticsearch 客户端。在 application.properties
或 application.yml
中添加 Elasticsearch 的配置:
properties:
# application.properties
spring.elasticsearch.rest.uris=http://localhost:9200
spring.elasticsearch.rest.username=root
spring.elasticsearch.rest.password=root
定义一个实体类,对应 Elasticsearch 中的文档:
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "blog")
public class Blog {
@Id
private String id;
private String title;
private String content;
private String category;
private Double price;
// Getters and setters
// ...
}
创建一个仓库接口,继承 ElasticsearchRepository
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface BlogRepository extends ElasticsearchRepository<Blog, String> {
// 可以添加自定义的搜索方法
}
可以在服务层中使用这个仓库接口
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class BlogService {
private final BlogRepository blogRepository;
@Autowired
public BlogService(BlogRepository blogRepository) {
this.blogRepository = blogRepository;
}
public Blog save(Blog blog) {
return blogRepository.save(blog);
}
public Optional<Blog> findById(String id) {
return blogRepository.findById(id);
}
// 其他业务方法...
}
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
@Service
public class AggregationService {
private final ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
public AggregationService(ElasticsearchRestTemplate elasticsearchRestTemplate) {
this.elasticsearchRestTemplate = elasticsearchRestTemplate;
}
public Double getAveragePriceForCategory(String category) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.termQuery("category.keyword", category))
.addAggregation(AggregationBuilders.avg("average_price").field("price"))
.build();
AggregatedPage<Blog> result = elasticsearchRestTemplate.queryForPage(searchQuery, Blog.class);
Avg averagePrice = result.getAggregations().get("average_price");
return averagePrice.getValue();
}
}
最后,创建一个 REST 控制器来处理 HTTP 请求:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequestMapping("/api/blogs")
public class BlogController {
private final BlogService blogService;
@Autowired
AggregationService aggregationService;
@Autowired
public BlogController(BlogService blogService) {
this.blogService = blogService;
}
@PostMapping
public Blog createBlog(@RequestBody Blog blog) {
return blogService.save(blog);
}
@GetMapping("/{id}")
public Blog getBlogById(@PathVariable String id) {
Optional<Blog> blog = blogService.findById(id);
return blog.orElse(null);
}
@GetMapping("/{category}")
public Blog getBlogById(@PathVariable String category) {
Optional<Blog> blog = aggregationService.getAveragePriceForCategory(category);
return blog.orElse(null);
}
// 其他端点...
}
总结:
首先构建了一个 NativeSearchQuery
,其中包含了一个筛选条件和一个聚合操作。筛选条件使用 QueryBuilders.termQuery
来匹配 category
字段的值。聚合操作使用 AggregationBuilders.avg
来计算 price
字段的平均值。
这个示例提供了一个简单的博客应用程序的基础结构,其中包含了 Elasticsearch 的集成。当然,实际应用中可能需要更多的配置和错误处理,以及复杂的查询方法。
转载自:https://juejin.cn/post/7357231056289185832