Java实战:SpringBoot+ElasticSearch 实现模糊查询

本文将详细介绍如何使用SpringBoot整合ElasticSearch,实现模糊查询、批量CRUD、排序、分页和高亮功能。我们将深入探讨ElasticSearch的相关概念和技术细节,以及如何使用SpringData Elasticsearch库简化开发过程。

1. 引言

ElasticSearch是一个基于Lucene构建的开源搜索引擎,它提供了一个分布式、多租户的全文搜索引擎,具有高可靠性、可扩展性和易用性。SpringBoot是Spring框架的一个模块,它简化了基于Spring的应用程序的开发和部署。将SpringBoot与ElasticSearch整合,可以实现强大的搜索功能,如模糊查询、批量CRUD、排序、分页和高亮等。

2. 环境准备

在开始之前,请确保已安装Java和Maven,并配置好相应的环境变量。接下来,我们将创建一个SpringBoot项目,并添加ElasticSearch依赖。
2.1 创建SpringBoot项目
使用Spring Initializr(https://start.spring.io/)创建一个SpringBoot项目,选择相应的依赖,如Spring Web、Spring Data Elasticsearch等。
2.2 添加ElasticSearch依赖
在项目的pom.xml文件中添加ElasticSearch依赖:

<dependencies>
    <!-- SpringBoot Elasticsearch 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <!-- 其他依赖 -->
</dependencies>

3. 配置ElasticSearch

在application.properties或application.yml文件中配置ElasticSearch相关属性:

# application.properties
spring.data.elasticsearch.cluster-name=my-cluster-name
spring.data.elasticsearch.cluster-nodes=localhost:9300

4. 创建ElasticSearch实体类

创建一个ElasticSearch实体类,用于映射ElasticSearch索引中的文档:

@Document(indexName = "blog", type = "article")
public class Article {
    @Id
    private String id;
    private String title;
    private String content;
    // getter and setter
}

5. 创建ElasticSearch repository接口

创建一个继承ElasticsearchRepository接口的repository接口,用于操作ElasticSearch索引:

public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
}

6. 实现模糊查询、批量CRUD、排序、分页、高亮

6.1 模糊查询
在ArticleRepository接口中添加一个自定义方法,用于实现模糊查询:

List<Article> findByTitleContaining(String title);

在Controller中添加一个接口,用于接收前端查询参数并调用repository方法:

@RestController
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;
    @GetMapping("/search")
    public List<Article> search(@RequestParam("title") String title) {
        return articleRepository.findByTitleContaining(title);
    }
}

6.2 批量CRUD
在Controller中添加一个接口,用于接收前端提交的批量操作请求:

@PostMapping("/batch")
public ResponseEntity<String> batch(@RequestBody List<Article> articles) {
    for (Article article : articles) {
        articleRepository.save(article);
    }
    return ResponseEntity.ok("批量操作成功!");
}

6.3 排序
在ElasticsearchRepository接口中,预定义了许多排序的方法,如findByTitleOrderByCreateTimeDesc。如果这些方法无法满足需求,可以使用@Query注解自定义查询,并指定排序规则:

@Query("{\"bool\": {\"must\": {\"match\": {\"title\": \"?0\"}}}}")
List<Article> findByTitle(String title, Sort sort);

6.4 分页
在ElasticsearchRepository接口中,预定义了许多分页的方法,如findByTitle(String title, Pageable pageable)。在Controller中,可以使用Pageable对象接收分页参数:

@GetMapping("/search")
public Page<Article> search(@RequestParam("title") String title, Pageable pageable) {
    return articleRepository.findByTitle(title, pageable);
}

6.5 高亮
在ElasticsearchRepository接口中,预定义了许多高亮的方法,如findByTitle(String title, Pageable pageable)。在Controller中,可以使用Pageable对象接收分页参数,并返回一个带有高亮信息的Page对象:

@GetMapping("/search")
public Page<Article> search(@RequestParam("title") String title, Pageable pageable) {
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    queryBuilder.withQuery(matchQuery("title", title));
    queryBuilder.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"));
    queryBuilder.withPageable(pageable);
    NativeSearchQuery searchQuery = queryBuilder.build();
    Page<Article> articles = articleRepository.search(searchQuery);
    return articles;
}

7. 完整代码示例

将上述所有代码片段组合在一起,我们得到了一个完整的SpringBoot+ElasticSearch实现模糊查询、批量CRUD、排序、分页和高亮的示例。下面是完整的代码示例:

// Article.java
@Document(indexName = "blog", type = "article")
public class Article {
    @Id
    private String id;
    private String title;
    private String content;
    // getter and setter
}
// ArticleRepository.java
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
    List<Article> findByTitleContaining(String title);
    Page<Article> findByTitle(String title, Pageable pageable);
}
// ArticleController.java
@RestController
public class ArticleController {
    @Autowired
    private ArticleRepository articleRepository;
    @GetMapping("/search")
    public Page<Article> search(@RequestParam("title") String title, Pageable pageable) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(matchQuery("title", title));
        queryBuilder.withHighlightFields(new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"));
        queryBuilder.withPageable(pageable);
        NativeSearchQuery searchQuery = queryBuilder.build();
        Page<Article> articles = articleRepository.search(searchQuery);
        return articles;
    }
    @PostMapping("/batch")
    public ResponseEntity<String> batch(@RequestBody List<Article> articles) {
        for (Article article : articles) {
            articleRepository.save(article);
        }
        return ResponseEntity.ok("批量操作成功!");
    }
}
// application.properties
spring.data.elasticsearch.cluster-name=my-cluster-name
spring.data.elasticsearch.cluster-nodes=localhost:9300

8. 总结

本文详细介绍了如何使用SpringBoot整合ElasticSearch,实现模糊查询、批量CRUD、排序、分页和高亮功能。请注意,实际部署时,您可能需要根据实际情况调整ElasticSearch集群配置,以及索引的创建和映射策略。此外,对于生产环境,您可能还需要考虑更多的错误处理和资源管理策略,例如处理可能出现的异常情况,以及优化查询性能等。
最后,如果您对SpringBoot+ElasticSearch整合或其他相关主题有更多的问题,欢迎在评论区留言讨论。

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 添加依赖 在`pom.xml`文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置elasticsearch 在`application.properties`文件中添加以下配置: ``` spring.data.elasticsearch.cluster-name=my-application spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300 ``` `cluster-name`表示elasticsearch集群的名称,`cluster-nodes`表示elasticsearch节点的地址。这里只有一个节点。 3. 创建实体类 创建一个实体类,用于映射elasticsearch中的文档。例如: ``` @Document(indexName = "my_index", type = "my_type") public class MyDocument { @Id private String id; private String name; private String content; // 省略getter和setter方法 } ``` `@Document`注解表示该类是一个elasticsearch文档,`indexName`表示文档所在的索引名称,`type`表示文档的类型。`@Id`注解表示该字段是文档的ID。 4. 创建Repository 创建一个Repository接口,继承`ElasticsearchRepository`接口。例如: ``` public interface MyDocumentRepository extends ElasticsearchRepository<MyDocument, String> { } ``` `MyDocument`表示文档类型,`String`表示文档ID的类型。 5. 使用Repository 在Service或Controller中使用`MyDocumentRepository`来操作elasticsearch。例如: ``` @Service public class MyService { @Autowired private MyDocumentRepository repository; public void save(MyDocument document) { repository.save(document); } public MyDocument findById(String id) { return repository.findById(id).orElse(null); } public List<MyDocument> search(String keyword) { SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.queryStringQuery(keyword)) .build(); return repository.search(searchQuery).getContent(); } } ``` `save`方法用于保存文档,`findById`方法用于根据ID查找文档,`search`方法用于搜索文档。`SearchQuery`表示搜索的查询条件,这里使用`QueryStringQuery`表示关键字查询。`NativeSearchQueryBuilder`用于构建查询条件。 6. 测试 编写测试类,测试`MyService`中的方法。例如: ``` @RunWith(SpringRunner.class) @SpringBootTest public class MyServiceTest { @Autowired private MyService service; @Test public void testSave() { MyDocument document = new MyDocument(); document.setId("1"); document.setName("test"); document.setContent("hello world"); service.save(document); } @Test public void testFindById() { MyDocument document = service.findById("1"); assertNotNull(document); assertEquals("test", document.getName()); assertEquals("hello world", document.getContent()); } @Test public void testSearch() { List<MyDocument> documents = service.search("hello"); assertEquals(1, documents.size()); assertEquals("1", documents.get(0).getId()); assertEquals("test", documents.get(0).getName()); assertEquals("hello world", documents.get(0).getContent()); } } ``` 先保存一个文档,然后根据ID查找文档,最后根据关键字搜索文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值