Spring Data Elasticsearch 的简单使用

目录

一、简介

二、配置

三、映射

[四、 常用方法](#四、 常用方法)

五、操作(重点)

1、对索引表的操作

2、对文档的操作(重点)

(1)、添加文档

(2)、删除文档

(3)、查询文档(重点)

[查询全部文档 (两种方式)](#查询全部文档 (两种方式))

matchQuery根据关键字拆分进行全局搜索

matchPhraseQuery短语搜索--完整搜索

rangeQuery范围搜索

termQuery精确搜索

boolQuery()复合查询

withPageable分页查询

withSorts对结果进行排序

高亮查询


一、简介

springData 操作ES类似于Mybatis-plus操作Mysql,都是简单易用

本博客基于springboot2最新方式操作 Elasticsearch7.12.1

二、配置

采用gradle构建 (maven构建一直失败)

implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'

最新的yml配置

复制代码
spring:
  elasticsearch:
    uris: http://ip:9200

三、映射

映射pojo

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName ="people_index") // 索引名字
public class People {
    @Id    
    private String id;    
    // Keyword类型不被分词索引    类型  分词器
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String name;    
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String address;    
    // index = false 不建立分词索引    
    @Field(type = FieldType.Long,index = true)
    private int age;
}

根据pojo创建索引

java 复制代码
@SpringBootTestclass 
EsDemo1ApplicationTests {
    
    // 直接注入使用
    @Autowired    
    ElasticsearchRestTemplate elasticsearchTemplate;    
  
    @Test
 void esTest(){
    // 创建索引    
    IndexOperations indexOperations = elasticsearchTemplate.indexOps(People.class);   
   if(!indexOperations.exists()) { // 当前索引不存在
        boolean result1 =indexOperations.create();// 只是创建索引 。mappings没有映射
        boolean result2 = indexOperations.putMapping();// 映射属性    
        System.out.println("创建结果:" + ",映射结果:" + result2);
    }else {
        System.out.println("文档已存在");
    }
}

验证索引表是否创建成功

GET people_index/_mapping

四、 常用方法

ElasticsearchRestTemplate 常用方法

java 复制代码
1、save :保存或者更新文档
elasticsearchRestTemplate.save(object);

2、index: 保存或更新文档数据到指定索引和类型中
IndexQuery indexQuery = new IndexQueryBuilder().withObject(object).build();
elasticsearchRestTemplate.index(indexQuery, IndexCoordinates.of(indexName));

3、get: 根据文档 ID 获取文档数据。
elasticsearchRestTemplate.get(id, DocumentClass.class);

4、update: 更新指定文档的数据。
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(id).withObject(updatedObject).build();
elasticsearchRestTemplate.update(updateQuery, IndexCoordinates.of(indexName));

5、delete: 删除指定文档。
elasticsearchRestTemplate.delete(id, IndexCoordinates.of(indexName));

6、exists: 判断指定文档是否存在。
elasticsearchRestTemplate.exists(id, IndexCoordinates.of(indexName));

7、search: 执行搜索操作,使用 Query 条件进行搜索。
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
     .withQuery(QueryBuilders.matchQuery("field", "value"))
     .build();
List<DocumentClass> resultList = elasticsearchRestTemplate.search(searchQuery, DocumentClass.class, IndexCoordinates.of(indexName));

8、count: 计算满足指定条件的文档数量。
NativeSearchQuery countQuery = new NativeSearchQueryBuilder()
     .withQuery(QueryBuilders.matchQuery("field", "value"))
     .build();
long count = elasticsearchRestTemplate.count(countQuery, IndexCoordinates.of(indexName));

IndexOperations 常用方法

java 复制代码
1、create():创建索引。如果索引已存在,则会抛出异常。

2、delete():删除索引。如果索引不存在,则会抛出异常。

3、exists():检查索引是否存在。

4、putMapping():为索引设置映射。MappingContext 是 Spring Data Elasticsearch 提供的用于获取实体类映射信息的接口。

5、refresh():刷新索引,使之可搜索最新添加的文档。在索引文档后,需要调用 refresh() 方法才能保证文档可以被搜索到。

6、getIndexSettings():获取索引的配置信息。

7、getAliases():获取索引的别名信息。

8、addAlias(AliasQuery aliasQuery):添加别名。

9、removeAlias(AliasQuery aliasQuery):移除别名。

10、getSettings():获取索引的详细配置信息。

11、updateSettings(UpdateSettingsRequest request):更新索引的配置信息。

其实真正常用的也就是

保存/修改文档

elasticsearchRestTemplate.save()

查询文档

elasticsearchRestTemplate.search()

以及NativeSearchQuery 搜索对象

五、操作(重点)

1、对索引表的操作

对索引表的操作常用的也就是,创建/修改、删除

创建就是上面提到的映射

删除索引表:

java 复制代码
@Test
void esTest2(){
    IndexOperations indexOperations = elasticsearchTemplate.indexOps(People.class);    
    boolean delete = indexOperations.delete();   // 删除索引      
    System.out.println("删除索引:"+delete);
 }

2、对文档的操作(重点)

对于ES来说,索引就是表,文档就是数据

(1)、添加文档

添加一条

java 复制代码
// 添加文档
@Test
void esTest3(){
    People people=new People();    
    people.setId("1232");    
    people.setName("张三");    
    people.setAge(32);    
    // 保存文档--save 根据文档id修改或者创建文档  
    People save = elasticsearchTemplate.save(people);   
    }

批量添加

java 复制代码
// 批量添加
@Test
void esTest4(){
    List<People> list= Arrays.asList(new People("1","李四","长沙",23),            
            new People("2","李四","长沙",23),            
            new People("3","李四","长沙",23),            
            new People("4","李四","长沙",23)
            );    
      Iterable<People> save1 = elasticsearchTemplate.save(list);    
      System.out.println("数据"+save1);
  }

检查是否添加完成

GET people_index/_search

(2)、删除文档

java 复制代码
// 删除操作
@Test
void esTest5(){
                                                
                                            // id   // 对应索引库    
String delete = elasticsearchTemplate.delete("1", People.class);    
}

除了根据id删除文档外,还可以根据条件删除文档,请类比下面的查询操作

(3)、查询文档(重点)

matchQuery按关键字查询(关键字也会被拆分),示例

java 复制代码
@Test
void query(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("address", "太阳")).build();    // 
    // 查询    
    SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery, People.class);    
    search1.forEach(System.out::println);
}

查询全部文档 (两种方式)

java 复制代码
// 第一种 ,不加查询条件
@Test
void query(){ 
    // 查询--全部文档
    SearchHits<People> search1 = elasticsearchTemplate.search(new NativeSearchQueryBuilder().build(), People.class);    
    search1.forEach(System.out::println);
  }
  
// 第二种
// 查询全部
//matchAllQuery
@Test
void query3(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // 根据关键字进行全局模糊搜索            
            .withQuery(QueryBuilders.matchAllQuery())         
            .build();    
            // 查询    
            SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
            search1.forEach(System.out::println);}

matchQuery根据关键字拆分进行全局搜索

java 复制代码
@Test
void query1(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // 根据关键字进行全局模糊搜索            
            .withQuery(QueryBuilders.matchQuery("李四")) // "李四"会被拆分成关键字进行搜索           
            .build();    
            // 查询    
            SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
            search1.forEach(System.out::println);
}

matchPhraseQuery短语搜索--完整搜索

不会对关键字的拆分搜索

java 复制代码
// 短语搜索
@Test
void query4(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // 根据关键字进行全局模糊搜索            
            .withQuery(QueryBuilders.matchPhraseQuery("address","长沙市"))     // "长沙市" 不会进行拆分
            .build();    
            // 查询    
            SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
            search1.forEach(System.out::println);
 }
 
 // 解释下什么是短语搜索
 比如查询 "小明爱吃葡萄"
 普通关键字查找(matchQuery),这句查找关键字会被拆分成 "小明","爱吃","葡萄" 等,查出的结果满足一个关键字即可,即查出来的结果可能会出现 "小明爱吃香蕉"
 短语搜索出来的结果 就是以"小明爱吃葡萄"为关键字去搜索,不会对关键字再进行拆分

rangeQuery范围搜索

适用于数值类型

java 复制代码
// 范围搜索
@Test
void query5(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // 根据关键字进行全局模糊搜索 lte <=  gte >=            
            .withQuery(QueryBuilders.rangeQuery("age").gte(10).lte(20))          
            .build();    
            // 查询    
            SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
            search1.forEach(System.out::println);
}

termQuery精确搜索

注意: 对于text类型且使用的ik分词的字段而言, termQuery的作用和matchPhraseQuery 类似,所以termQuery 适用于keyword类型的字段和数值类型的字段

java 复制代码
// 精确搜索
@Test
void query6(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // 根据关键字进行全局模糊搜索 lte <=  gte >=            
            .withQuery(QueryBuilders.termQuery("age",15))
            .build();    
            // 查询    
            SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
            search1.forEach(System.out::println);
 }

boolQuery()复合查询

对于优先级别问题 使用多个must 来处理

java 复制代码
// 复合查询
@Test
void query7(){
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
            // boolQuery 符合查询,must必须  should 或者            
            // name=李四 ||age>=30            
            // QueryBuilders.boolQuery().should(QueryBuilders.termQuery("name","李四")).should(QueryBuilders.rangeQuery("age").gte(30))            
            // name=李四 && age>=30            
            // QueryBuilders.boolQuery().must(QueryBuilders.termQuery("name","李四")).must(QueryBuilders.rangeQuery("age").gte(30))            
            //  (name=李四 || age>=25) && age <=30  使用must 处理优先级问题            
            .withQuery(QueryBuilders.boolQuery()
                    .must(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("name","李四")).should(QueryBuilders.rangeQuery("age").gte(25)))
                    .must(QueryBuilders.rangeQuery("age").lte(30)))
            .build();    
           // 查询    
           SearchHits<People> search1 = elasticsearchTemplate.search(searchQuery,People.class);    
           search1.forEach(System.out::println);
 }

withPageable分页查询

需要对查询结果进行封装

java 复制代码
@Test
void query8() throws JsonProcessingException {
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()                                                                                
                 // 页码(从0开始) 每页条数                                                    
                .withPageable(PageRequest.of(0,2))
                .build();    
            // 查询    
            SearchHits<People> search = elasticsearchTemplate.search(searchQuery, People.class);    
            // 对查询结果进行封装--Page    
            SearchPage<People> searchHits = SearchHitSupport.searchPageFor(search, searchQuery.getPageable());    
            System.out.println("当前页码(从0开始):getNumber:"+searchHits.getNumber());    
            System.out.println("总页数:getTotalPages :"+searchHits.getTotalPages());    
            System.out.println("每页的最大数据条数:getSize: "+searchHits.getSize());    
            System.out.println("是否有下一页数据:hasNext: "+searchHits.hasNext());    
            System.out.println("是否有上一页数据:hasPrevious: "+searchHits.hasPrevious());    
            System.out.println("当前页数据:getContent: "+searchHits.getContent());   
             
            String s = objectMapper.writeValueAsString(searchHits);                
            System.out.println("json:"+s);
}

withSorts对结果进行排序

java 复制代码
@Test
void query8() throws JsonProcessingException {
    // 创建查询  字段--索引    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()

              // 查询全部            
              .withQuery(QueryBuilders.matchAllQuery())
             // 根据 age 字段进行从大到小排序            
                                         // 字段             排序规则
             .withSorts(SortBuilders.fieldSort("age").order(SortOrder.DESC))
            .build();    
            // 查询    
            SearchHits<People> search = elasticsearchTemplate.search(searchQuery, People.class);    
            search.forEach(System.out::println);
   }

高亮查询

把查询结果的关键字进行高亮处理

java 复制代码
// 高亮查询
@Test
void query9() throws JsonProcessingException {
    // 创建查询  字段--索引    
    // 创建高亮设置    
    HighlightBuilder highlightBuilder=new HighlightBuilder();    
    // 设置高亮的结果字段                        结果前面添加内容                                后续添加内容    
    highlightBuilder.field("address").preTags("<span style=\"color:red\">").postTags("</span>");    
    highlightBuilder.field("name").preTags("<span style=\"color:red\">").postTags("</span>");    
    NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()

            .withQuery(QueryBuilders.matchQuery("address","长沙"))
            // 处理高亮            
            .withHighlightBuilder(highlightBuilder)
            .build();    
            // 查询    
            SearchHits<People> search = elasticsearchTemplate.search(searchQuery, People.class);    
            // 查询结果为SearchHits --SearchHit为封装的单个数据,高亮数据在highlightFields 中    
            List<SearchHit<People>> searchHits = search.getSearchHits();    
            searchHits.forEach(System.out::println);
}
相关推荐
码路飞12 分钟前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
序安InToo15 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12315 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记18 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0518 分钟前
VS Code 配置 Markdown 环境
后端
navms22 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0522 分钟前
离线数仓的优化及重构
后端
Nyarlathotep011323 分钟前
gin01:初探gin的启动
后端·go
JxWang0523 分钟前
安卓手机配置通用多屏协同及自动化脚本
后端
JxWang0524 分钟前
Windows Terminal 配置 oh-my-posh
后端