需要的依赖版本
1.SpringBoot:3.x
2.ElasticSearch:8.x
3.JDK:17(终于不用1.8了)

先给出pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>es</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>es</name>
    <description>es</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.17.4</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>5.4.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

给出DTO示例

@Document(indexName = "student")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentDTO {
    @Id
    @Field(type = FieldType.Long)
    private Long id;

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

    @Field(type = FieldType.Integer)
    private Integer age;

    @Field(type = FieldType.Keyword)
    private String phoneNumber;

    @Field(type = FieldType.Keyword)
    private String sex;

    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private Date createTime;


    public StudentDTO(Long id, String name, Integer age, String phoneNumber, String sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.phoneNumber = phoneNumber;
        this.sex = sex;
    }
}

创建单元测试类

新版本用的是ElasticsearchOperations

@SpringBootTest
public class EsApplicationTests {
	@Autowired
    private ElasticsearchOperations restTemplate;
	//执行的代码逻辑
}

ElasticsearchOperations 中封装了挺多方法,以下简单介绍几个

判断索引是否存在

@Test
public void existsIndex() {
    IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
    boolean exists = indexOperations.exists();
    System.out.println(exists);
}

创建索引

@Test
public void createIndex() {
    IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
    // 不存在
    if(!indexOperations.exists()){
        // 创建索引
        indexOperations.create();
    }
    //设置字段mapping
    restTemplate.indexOps(StudentDTO.class).putMapping();
}

删除索引

@Test
public void deleteIndex() {
    IndexOperations indexOperations = restTemplate.indexOps(StudentDTO.class);
    boolean delete = indexOperations.delete();
    System.out.println(delete);
}

插入单行数据

@Test
public void insert(){
    StudentDTO studentDTO = new StudentDTO();
    studentDTO.setId(1L);
    studentDTO.setAge(21);
    studentDTO.setCreateTime(new Date());
    studentDTO.setName("张三");
    studentDTO.setPhoneNumber("18392020202");
    studentDTO.setSex("男");

    StudentDTO saved = restTemplate.save(studentDTO);
    System.out.println(saved);
}

更新单行数据

本质是通过id字段(@Id注解)更新
(方法1)

@Test
public void update(){
    StudentDTO studentDTO = new StudentDTO();
    studentDTO.setId(1L);
    studentDTO.setAge(18);
    studentDTO.setCreateTime(new Date());
    studentDTO.setName("李四");
    studentDTO.setPhoneNumber("13904535353");
    studentDTO.setSex("男");

    StudentDTO saved = restTemplate.save(studentDTO);
    System.out.println(saved);
}

(方法2)

@Test
void  update2(){
    StudentDTO studentDTO = restTemplate.get("1", StudentDTO.class);
    assert studentDTO != null;
    System.out.println(studentDTO);
    studentDTO.setPhoneNumber("18749503962");
    StudentDTO saved = restTemplate.save(studentDTO);
    System.out.println(saved);
}

批量插入

@Test
public void batchInsert() {
    List<StudentDTO> list = new ArrayList<>();
    list.add(new StudentDTO(2L, "李四", 12, "17895937593", "男"));
    list.add(new StudentDTO(3L, "王二麻子", 31, "18429053823", "男"));
    list.add(new StudentDTO(4L, "子涵", 18, "13684924580", "女"));
    list.add(new StudentDTO(5L, "寰寰", 60, "15920483957", "女"));
    list.add(new StudentDTO(6L, "皇太极", 89, "15528091902", "男"));
    Iterable<StudentDTO> result = restTemplate.save(list);
    System.out.println(result);
}

查询指定文档

@Test
public void  searchById(){
    StudentDTO studentDTO = restTemplate.get("3", StudentDTO.class);
    assert studentDTO != null;
    System.out.println(studentDTO);
}

删除指定文档

@Test
public void  deleteById() {
    String delete = restTemplate.delete("3", StudentDTO.class);
    System.out.println(delete);
}

查询所有数据

@Test
public void searchAll(){
    SearchHits<StudentDTO> search = restTemplate.search(Query.findAll(), StudentDTO.class);
    List<SearchHit<StudentDTO>> searchHits = search.getSearchHits();
    List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
    System.out.println(studentDTOS);
}

根据条件查询

@Test
public void matchQuery(){
    Query query = NativeQuery.builder().withQuery(q -> q
            .match(m -> m
                    .field("phoneNumber") //要查询的字段
                    .query("15528091902") //要查询的字段值
            )).build();
    SearchHits<StudentDTO> searchHits = restTemplate.search(query, StudentDTO.class);
    List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
    System.out.println(studentDTOS);
}

分页+排序查询

@Test
public void pageSearch() {
    Query query = NativeQuery.builder()
	    .withQuery(Query.findAll())
	    .withPageable(Pageable.ofSize(3).withPage(0))
	    .withSort(Sort.by("age").descending())
	    .build();
    SearchHits<StudentDTO> searchHits = restTemplate.search(query, StudentDTO.class);
    List<StudentDTO> studentDTOS = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
    System.out.println(studentDTOS);
}

原生DSL查询

/*///原始DSL查询
GET /student/_search
{
    "query":{
        "bool":{
            "must": [{
                "match":{
                    "sex":"男"
                }
            },{
                "range":{
                    "age":{
                        "gte":10,
                        "lte":50
                    }
                }
            }]
        }
    }
}*/


@Test
public void stringQuery() {

    //搜索性别 男 ,电话号码 159,年龄范围是 10~50之间的
    String dsl = """
               {"bool":{"must":[{"match":{"sex":"男"}},{"range":{"age":{"gte":10,"lte":50}}}]}}
            """;
    Query query = new StringQuery(dsl);
    List<SearchHit<StudentDTO>> searchHitList = restTemplate.search(query, StudentDTO.class).getSearchHits();
    List<StudentDTO> studentDTOS = searchHitList.stream().map(SearchHit::getContent).collect(Collectors.toList());
    System.out.println(studentDTOS);
}

聚合查询

@Test
public void aggQuery() {
    Query query = NativeQuery.builder()
            .withAggregation("category_group", Aggregation.of(a -> a.terms(o-> o.field("sex").size(2))))
            .build();

    SearchHits<StudentDTO> searchHitList = restTemplate.search(query, StudentDTO.class);

    //获取聚合数据
    ElasticsearchAggregations aggregationsContainer = (ElasticsearchAggregations) searchHitList.getAggregations();
    Map<String, ElasticsearchAggregation> aggregations = Objects.requireNonNull(aggregationsContainer).aggregationsAsMap();

    //获取对应名称的聚合
    ElasticsearchAggregation aggregation = aggregations.get("category_group");
    Buckets<StringTermsBucket> buckets = aggregation.aggregation().getAggregate().sterms().buckets();

    //打印
    buckets.array().forEach(o -> System.out.println("key:"+ o.key().stringValue() + ", value" + o.docCount()));
    List<StudentDTO> studentDTOS = searchHitList.stream().map(SearchHit::getContent).collect(Collectors.toList());
    System.out.println(studentDTOS);
}
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐