work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Spring Boot 集成ElasticSearch

Posted on 2020-05-05 16:16  work hard work smart  阅读(971)  评论(0编辑  收藏  举报

1、创建SpringBoot工程。

spring boot版本为2.2.6, 增加spring-boot-starter-data-elasticsearch

<?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>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sp-esearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sp-esearch</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</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-data-elasticsearch</artifactId>
            <!--<version>2.2.2.RELAESE</version>-->
        </dependency>

     
    </dependencies>

   

</project>

  

2、增加配置

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 127.0.0.1:9300

  

3、使用单元测试创建索引

@SpringBootTest
class SpEsearchApplicationTests {

    @Test
    void contextLoads() {
    }

}

创建Student类

@Document(indexName = "stu", type = "_doc")
public class Student {

    @Id
    private Long stuId;

    @Field(store = true)
    private String name;

    @Field(store = true)
    private Integer age;

    public Long getStuId() {
        return stuId;
    }

    public void setStuId(Long stuId) {
        this.stuId = stuId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 

创建索引  

public class ESTest extends  SpEsearchApplicationTests {

    @Autowired
    private ElasticsearchTemplate esTemplate;

    //创建索引
    @Test
    public void createIndex(){
        Student stu = new Student();
        stu.setStuId(1000L);
        stu.setName("Nick");
        stu.setAge(20);
        IndexQuery indexQuery = new IndexQueryBuilder().withObject(stu).build();
        esTemplate.index(indexQuery);
    }

}

  

执行单元测试方法,结果显示索引已经创建成功

数据浏览

 

4、删除索引

    @Test
    public void deleteIndex(){
        esTemplate.deleteIndex(Student.class);
    }

  

注意: 不建议使用ElasticsearchTemplate对索引进行管理(创建索引,更新映射,删除索引)。

索引就像是数据库或者数据库中的表,我们平时不会通过Java代码频繁的去创建修改删除数据库或者表,之后针对数据做CRUD操作,在es中也是同理,

 

5、更新文档数据。

Id为1000这条数据

    @Test
    public void updateStuDoc(){
        Map<String,Object> source = new HashMap<>();
        source.put("sign","I am not a english teacher");
        source.put("money",88.8f);
        source.put("age","100");

        IndexRequest indexRequest = new IndexRequest();
        indexRequest.source(source);
        UpdateQuery query = new UpdateQueryBuilder().withClass(Student.class)
                .withId("1000")
                .withIndexRequest(indexRequest)
                .build();
        esTemplate.update(query);
    }

  

6、查询文档数据

    @Test
    public void getStuInfo(){
        GetQuery getQuery = new GetQuery();
        getQuery.setId("1000");
        Student student = esTemplate.queryForObject(getQuery, Student.class);
        System.out.println(student);
    }

  

返回结果

Student{stuId=1000, name='Nick 2', age=100, money=88.8, sign='I am not a english teacher', description='I am a english teacher'}

  

7、删除文档数据

    @Test
    public void deleteStuDoc(){
       esTemplate.delete(Student.class,"1000");

    }

  

 8、文档分页查询

1) 创建5条数据

   @Test
    public void createIndex(){
        for(int i = 0 ; i < 5; i++){
            Student stu = new Student();
            stu.setStuId(1000L + i);
            stu.setName("Nick" + i);
            stu.setAge(20 + i);
            stu.setMoney(18.9f + i);
            stu.setSign("I am a teacher");
            stu.setDescription("I am a english teacher " + i);
            IndexQuery indexQuery = new IndexQueryBuilder().withObject(stu).build();
            esTemplate.index(indexQuery);
        }

    }

 

2) 分页查询

    @Test
    public void searchStuDoc(){
        Pageable pageable = PageRequest.of(0,10);
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("description","a teacher"))
                .withPageable(pageable).build();
      AggregatedPage<Student> pageStu = esTemplate.queryForPage(query,Student.class);

       System.out.println("总分页数:" +   pageStu.getTotalPages());
       List<Student> stuList = pageStu.getContent();
       for(Student student : stuList){
           System.out.println(student);
       }

    }  

返回结果如下:

总分页数:1
Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am a english teacher 0'}
Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am a english teacher 1'}
Student{stuId=1002, name='Nick2', age=22, money=20.9, sign='I am a teacher', description='I am a english teacher 2'}
Student{stuId=1003, name='Nick3', age=23, money=21.9, sign='I am a teacher', description='I am a english teacher 3'}
Student{stuId=1004, name='Nick4', age=24, money=22.9, sign='I am a teacher', description='I am a english teacher 4'}

  

 8、文档高亮查询

 @Test
    public void highlightStuDoc(){
        String preTag = "<font color='red'>";
        String postTag = "</font>";
        Pageable pageable = PageRequest.of(0,2);
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("description","a teacher"))
                .withHighlightFields(new HighlightBuilder.Field("description").preTags(preTag).postTags(postTag))
                .withPageable(pageable).build();
        AggregatedPage<Student> pageStu = esTemplate.queryForPage(query, Student.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
               List<Student> stuHighlight = new ArrayList<>();
                SearchHits hits =  searchResponse.getHits();
               for(SearchHit h: hits){
                  HighlightField highlightField = h.getHighlightFields().get("description");
                  Integer stuId = (Integer)h.getSourceAsMap().get("stuId");
                  String name = (String)h.getSourceAsMap().get("name");
                  Integer age = (Integer)h.getSourceAsMap().get("age");
                  String sign = (String)h.getSourceAsMap().get("sign");
                  Object money = h.getSourceAsMap().get("money");
                  //高亮数据
                  String description = highlightField.getFragments()[0].toString();
                  Student studentHL = new Student();
                  studentHL.setDescription(description);
                  studentHL.setStuId(Long.parseLong(stuId.toString()));
                  studentHL.setName(name);
                  studentHL.setAge(age);
                  studentHL.setSign(sign);
                  studentHL.setMoney(Float.parseFloat(money.toString()));
                  stuHighlight.add(studentHL);
               }
               if(!stuHighlight.isEmpty()){
                   return  new AggregatedPageImpl<>((List<T>) stuHighlight);
               }
                return null;
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });

        System.out.println("总分页数:" +   pageStu.getTotalPages());
        List<Student> stuList = pageStu.getContent();
        for(Student student : stuList){
            System.out.println(student);
        }

    }

  

返回结果如下

总分页数:1
Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 0'}
Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 1'}

  

9、排序

查询结果以money进行降序

 @Test
    public void sortStuDoc(){
        String preTag = "<font color='red'>";
        String postTag = "</font>";
        Pageable pageable = PageRequest.of(0,10);

        //查询结果以money进行排序
        SortBuilder sortBuilder = new FieldSortBuilder("money")
                .order(SortOrder.DESC);
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("description","a teacher"))
                .withHighlightFields(new HighlightBuilder.Field("description").preTags(preTag).postTags(postTag))
                .withSort(sortBuilder)
                .withPageable(pageable).build();
        AggregatedPage<Student> pageStu = esTemplate.queryForPage(query, Student.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                List<Student> stuHighlight = new ArrayList<>();
                SearchHits hits =  searchResponse.getHits();
                for(SearchHit h: hits){
                    HighlightField highlightField = h.getHighlightFields().get("description");
                    Integer stuId = (Integer)h.getSourceAsMap().get("stuId");
                    String name = (String)h.getSourceAsMap().get("name");
                    Integer age = (Integer)h.getSourceAsMap().get("age");
                    String sign = (String)h.getSourceAsMap().get("sign");
                    Object money = h.getSourceAsMap().get("money");
                    //高亮数据
                    String description = highlightField.getFragments()[0].toString();
                    Student studentHL = new Student();
                    studentHL.setDescription(description);
                    studentHL.setStuId(Long.parseLong(stuId.toString()));
                    studentHL.setName(name);
                    studentHL.setAge(age);
                    studentHL.setSign(sign);
                    studentHL.setMoney(Float.parseFloat(money.toString()));
                    stuHighlight.add(studentHL);
                }
                if(!stuHighlight.isEmpty()){
                    return  new AggregatedPageImpl<>((List<T>) stuHighlight);
                }
                return null;
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                return null;
            }
        });

        System.out.println("总分页数:" +   pageStu.getTotalPages());
        List<Student> stuList = pageStu.getContent();
        for(Student student : stuList){
            System.out.println(student);
        }

    }  

返回如下:

总分页数:1
Student{stuId=1004, name='Nick4', age=24, money=22.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 4'}
Student{stuId=1003, name='Nick3', age=23, money=21.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 3'}
Student{stuId=1002, name='Nick2', age=22, money=20.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 2'}
Student{stuId=1001, name='Nick1', age=21, money=19.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 1'}
Student{stuId=1000, name='Nick0', age=20, money=18.9, sign='I am a teacher', description='I am <font color='red'>a</font> english <font color='red'>teacher</font> 0'}

 

对多个字段进行排序。如对money和age进行排序