spring-boot操作elasticsearch

一、环境准备

springboot与elasticsearch的更新都非常快,为了避免兼容性问题,要注意下选择的版本问题。具体的可参考官网 --> ++springboot与elasticsearch版本兼容性++

1.1导入依赖

XML 复制代码
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>2.7.18</version>
  </dependency>
  <dependency>
      <groupId>jakarta.json</groupId>
      <artifactId>jakarta.json-api</artifactId>
      <version>2.0.1</version>
   </dependency>
</dependencies>
 

1.2application.properties文件配置

javascript 复制代码
spring.elasticsearch.rest.uris=http://localhost:9200
spring.elasticsearch.rest.username=dev
spring.elasticsearch.rest.password=123456

1.3创建实体对象

java 复制代码
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;


@Document(indexName = "employee")
@Data
public class Employee {

    @Id
    private int id;

    @Field(name = "name")
    private String name;

    @Field(name = "addr", type = FieldType.Keyword)
    private String addr;

}

该实体类加上@Document注解之后,程序启动后就会自动向ED发送创建索引的请求(若没有则创建)。

1.4创建Repository接口

java 复制代码
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface EmployeeRepository extends ElasticsearchRepository<Employee, Integer> {
}

1.5Crud测试案例

使用该接口可方便对索引进行增删查改。例子比较简单,我们直接写个单元测试。代码如下:

java 复制代码
import gamecontext.admin.elasticsearch.Employee;
import gamecontext.admin.elasticsearch.EmployeeRepository;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest()
@RunWith(SpringRunner.class)
public class ElasticsearchTest {

    @Autowired
    private EmployeeRepository repository;

    @Test
    public void testSave() {
        Employee p = new Employee();
        p.setId(3);
        p.setAddr("北京");
        p.setName("Tim");
        repository.save(p);
        Assert.assertEquals("Tim", repository.findById(3).get().getName());
    }

    @Test
    public void testDelete() {
        Employee p = new Employee();
        p.setId(4);
        p.setAddr("北京");
        p.setName("Tim");
        repository.save(p);
        repository.deleteById(4);
        Assert.assertFalse(repository.findById(4).isPresent());
    }

    @Test
    public void testUpdate() {
        Employee p = repository.findById(3).get();
        p.setName("南京");
        repository.save(p);
        Assert.assertEquals(repository.findById(3).get().getName(), "南京");
    }

}

二、使用QueryBuilder进行文档的复杂查询

ElasticsearchRepository只能对文档进行简单的增删查改,如果遇到复杂的全文搜索,则需要借助QueryBuilder和ElasticsearchRestTemplate相关API

2.1数据准备

往索引插入3条文档,数据如下

2.2进行must查询

java 复制代码
import gamecontext.admin.elasticsearch.Employee;
import gamecontext.admin.elasticsearch.EmployeeRepository;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest()
@RunWith(SpringRunner.class)
public class ElasticsearchTest2 {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

   @Test
    public void testMust() {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name", "李"))
                .must(QueryBuilders.matchQuery("name", "四"));
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

        SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
        Assert.assertTrue(hits.stream().findFirst().isPresent());
        Assert.assertEquals(hits.stream().findFirst().get().getContent().getName(), "李四");
    }
}

等效的Kibana命令

2.3进行range查询

java 复制代码
    @Test
    public void testRange() {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        RangeQueryBuilder builder = QueryBuilders.rangeQuery("age").lte(20).gte(10);
        nativeSearchQueryBuilder.withQuery(builder);
        SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
        Assert.assertEquals(2, hits.getTotalHits());
    }

等效的Kibana命令

2.4进行sort排序

java 复制代码
    @Test
    public void testSort() {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC));
//                .withSort(SortBuilders.fieldSort("name").order(SortOrder.ASC));
        SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
        Employee p1 = hits.stream().findFirst().get().getContent();
        List<SearchHit<Employee>> list = hits.stream().collect(Collectors.toUnmodifiableList());
        Assert.assertTrue(list.get(0).getContent().getAge()>list.get(1).getContent().getAge());
        Assert.assertTrue(list.get(1).getContent().getAge()>list.get(2).getContent().getAge());
    }

等效的Kibana命令

默认情况下,text类型的字段是不能排序的,否则会报以下异常,

bash 复制代码
Caused by: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [name] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]]

翻译如下:

XML 复制代码
默认情况下,文本字段禁用字段数据。在[region]上设置fielddata=true,以便通过取消反转索引将fielddata加载到内存中。请注意,这可能会占用大量内存。

解决方法:

  • 将name字段设置为keyword类型
  • 将name字段的fielddata()为true

2.5进行文本高亮

可以使用HighlightBuilder 类来设置查询结果文本高亮

java 复制代码
 @Test
    public void testHighlight() {
        String PRE_TAG = "<mark>";
        String POST_TAG = "</mark>";
        HighlightBuilder.Field titleField = new HighlightBuilder.Field("name");
        titleField.preTags(PRE_TAG);
        titleField.postTags(POST_TAG);

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name", "李"));
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        nativeSearchQueryBuilder.withHighlightFields(titleField);
        SearchHits<Employee> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
        Map<String, List<String>> files = search.getSearchHits().stream().findFirst().get().getHighlightFields();
        Assert.assertFalse(CollectionUtils.isEmpty(files));
    }
相关推荐
qq_5895681040 分钟前
springbootweb案例,出现访问 http://localhost:8080/list 一直处于浏览器运转阶段
java·网络协议·http·list·springboot
AC赳赳老秦1 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw
历程里程碑3 小时前
4 Git远程协作:从零开始,玩转仓库关联与代码同步(带实操代码讲解)
大数据·c++·git·elasticsearch·搜索引擎·gitee·github
苍煜3 小时前
MySQL分库分表和ES到底怎么选?
数据库·mysql·elasticsearch
南棱笑笑生4 小时前
20260504关闭右上角显示的fps参数等信息【NVIDIA显卡】
搜索引擎
摇滚侠8 小时前
DSL 学习 ElasticSearch 主要就是学习 DSL 查询语言
学习·elasticsearch·jenkins
AI周红伟9 小时前
一天赚5个亿的超级个体天花板李一舟:普通人可借鉴的6点
大数据·人工智能·搜索引擎·copilot·openclaw
用户97471381214010 小时前
Elasticsearch 文档版本控制实验手册
elasticsearch
摇滚侠11 小时前
自动补全 黑马 Elasticsearch 全套教程,黑马旅游网案例
大数据·elasticsearch·搜索引擎
逸Y 仙X11 小时前
文章二十一:ElasticSearch 词项查询与调度查询实战
java·大数据·数据库·elasticsearch·搜索引擎