Elasticsearch springboot整合ES

起因:在项目开发过程中,要使用到搜索 引擎来对一些关键字实现逆向查询,如果仅用模糊搜索,那么搜索的时间会根据数据量的增大而增大,对比之下就学了elasticsearch,也记录一下,常常回顾。


1. Springboot整合Elasticsearch进行索引操作

POM中增加依赖


    org.springframework.boot
    spring-boot-starter-data-elasticsearch

yaml配置

# 端口一定要9300
spring:
  data:
    elasticsearch:
      cluster-name: icoding-es
      cluster-nodes: 47.92.163.109:9300

创建映射的po

package com.icodingedu.po;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

//indexName相当于给索引明名
//type相当于文档类型
@Data
@Document(indexName = "index_user",type = "_doc",shards = 3,replicas = 1)
public class UserBo {
    //index的doc的id和数据的id一致
    @Id
    private String id;

    //默认不是存储节点,要声明
    @Field(store = true,index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String nickname;

    @Field(store = true)
    private Integer sex;

    @Field(store = true)
    private Double consume;

    @Field(store = true,index = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
    private String review;
}

创建索引的controller

package com.icodingedu.controller;

import com.icodingedu.po.UserBo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ESUserController {

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    @GetMapping("/create_index")
    @ResponseBody
    public String createIndex(){
        UserBo userBo = new UserBo();
        userBo.setId("1001");
        userBo.setConsume(1899.66);
        userBo.setNickname("空中雄鹰");
        userBo.setReview("icoding edu 艾编程课程非常不错,学起来很给力");
        userBo.setSex(1);

        IndexQuery indexQuery = new IndexQueryBuilder()
                .withObject(userBo)
                .build();
        elasticsearchTemplate.index(indexQuery);
        return "index/mapping/document 一起创建完成";
    }
}

更新索引的mapping

// 只需要在po里加上字段既可以
// 创建的时候给赋值
// 更新的时候elasticsearchTemplate会根据po的变化判断是否更新
// 在elasticsearchTemplate.index(indexQuery)操作时如果没有index则新建,如果有就创建数据

删除index

@GetMapping("/delete-index")
@ResponseBody
public String deleteIndex(){
  elasticsearchTemplate.deleteIndex(UserBo.class);
  return "删除成功";
}

ElasticsearchTemplate一般用于对文档数据进行检索应用

  • 对于index的mapping还是使用json来创建
  • ET的部分注解不一定生效

2. Springboot对ES文档进行操作

更新document

    @GetMapping("/update")
    @ResponseBody
    public String updateIndex(){

        Map data = new HashMap();
        data.put("username","jackwang");
        data.put("consume",7888.99);

        IndexRequest indexRequest = new IndexRequest();
        indexRequest.source(data);

        UpdateQuery updateQuery = new UpdateQueryBuilder()
                .withClass(UserBo.class)
                .withId("1001")
                .withIndexRequest(indexRequest)
                .build();

        elasticsearchTemplate.update(updateQuery);
        return "更新成功";
    }

删除document

    @GetMapping("/delete/{id}")
    @ResponseBody
    public String deleteDocument(@PathVariable("id") String uid){
        elasticsearchTemplate.delete(UserBo.class,uid);
        return "删除id:"+uid;
    }

根据id获得doc数据

    @GetMapping("/get/{id}")
    @ResponseBody
    public String getIndex(@PathVariable("id") String uid){

        GetQuery query = new GetQuery();
        query.setId(uid);

        UserBo userBo = elasticsearchTemplate.queryForObject(query,UserBo.class);
        return userBo.toString();
    }

3. Springboot对ES文档进行分页查询

// ES中已有的index映射对象
package com.icodingedu.po;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

@Data
@Document(indexName = "index_customer",type = "_doc")
public class CustomerPo {
    @Id
    private String id;

    @Field(store=true)
    private Integer age;

    @Field(store=true)
    private String username;

    @Field(store=true)
    private String nickname;
    @Field(store=true)
    private Float consume;

    @Field(store=true)
    private String desc;

    @Field(store=true)
    private Integer sex;

    @Field(store=true)
    private String birthday;

    @Field(store=true)
    private String city;

    @Field(store=true)
    private String faceimg;
}

查询分页的controller

    @GetMapping("/list")
    @ResponseBody
    public String getList(){
        //3.定义分页
        Pageable pageable = PageRequest.of(0,2);
        //2.定义query对象
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("desc","艾编程 学习"))
                .withPageable(pageable)
                .build();
        //1.先写查询
        AggregatedPage customerPos = elasticsearchTemplate.queryForPage(query,CustomerPo.class);
        System.out.println("总页数:"+customerPos.getTotalPages());
        System.out.println("总记录数:"+customerPos.getTotalElements());
        List customerPoList = customerPos.getContent();
        for (CustomerPo customerPo:customerPoList) {
            System.out.println(customerPo.toString());

        }
        return "查询完成";
    }

4. Springboot对ES文档实现高亮查询

//目前已加入高亮的字符,但会报错,无法获得值
    @GetMapping("/listhiglight")
    @ResponseBody
    public String getListHighLight(){
        //4.定义高亮的字符
        String preTag = "";
        String postTag = "";
        //3.定义分页
        Pageable pageable = PageRequest.of(0,2);
        //2.定义query对象
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("desc","艾编程 学习"))
                .withHighlightFields(new HighlightBuilder.Field("desc").preTags(preTag).postTags(postTag))
                .withPageable(pageable)
                .build();
        //1.先写查询,参数里增加高亮的实现
        AggregatedPage customerPos = elasticsearchTemplate.queryForPage(query, CustomerPo.class, new SearchResultMapper() {
            @Override
            public  AggregatedPage mapResults(SearchResponse searchResponse, Class aClass, Pageable pageable) {
                return null;
            }

            @Override
            public  T mapSearchHit(SearchHit searchHit, Class aClass) {
                return null;
            }
        });
        System.out.println("总页数:"+customerPos.getTotalPages());
        System.out.println("总记录数:"+customerPos.getTotalElements());
        List customerPoList = customerPos.getContent();
        for (CustomerPo customerPo:customerPoList) {
            System.out.println(customerPo.toString());

        }
        return "查询完成";
    }

实现高亮完整代码

    @GetMapping("/listhiglight")
    @ResponseBody
    public String getListHighLight(){
        //4.定义高亮的字符
        String preTag = "";
        String postTag = "";
        //3.定义分页
        Pageable pageable = PageRequest.of(0,2);
        //2.定义query对象
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("desc","艾编程 学习"))
                .withHighlightFields(new HighlightBuilder.Field("desc").preTags(preTag).postTags(postTag))
                .withPageable(pageable)
                .build();
        //1.先写查询,参数里增加高亮的实现
        AggregatedPage customerPos = elasticsearchTemplate.queryForPage(query, CustomerPo.class, new SearchResultMapper() {
            @Override
            public  AggregatedPage mapResults(SearchResponse searchResponse, Class aClass, Pageable pageable) {
                List customerPoList = new ArrayList();
                SearchHits searchHits = searchResponse.getHits();
                for (SearchHit h: searchHits) {
                    HighlightField highlightField = h.getHighlightFields().get("desc");
                    String desc = highlightField.fragments()[0].toString();
                    CustomerPo customerPoHighlight = new CustomerPo();
                    customerPoHighlight.setAge((Integer)h.getSourceAsMap().get("age"));
                    customerPoHighlight.setBirthday(h.getSourceAsMap().get("birthday").toString());
                    customerPoHighlight.setCity(h.getSourceAsMap().get("city").toString());
                    customerPoHighlight.setConsume(Float.valueOf(h.getSourceAsMap().get("consume").toString()));
                    customerPoHighlight.setDesc(desc);//这就是把高亮的字段替换给原字段
                    customerPoHighlight.setFaceimg(h.getSourceAsMap().get("faceimg").toString());
                    customerPoHighlight.setId(h.getSourceAsMap().get("id").toString());
                    customerPoHighlight.setNickname(h.getSourceAsMap().get("nickname").toString());
                    customerPoHighlight.setSex((Integer)h.getSourceAsMap().get("sex"));
                    customerPoHighlight.setUsername(h.getSourceAsMap().get("username").toString());
                    customerPoList.add(customerPoHighlight);
                }
                if(customerPoList.size()>0){
                    return new AggregatedPageImpl<>((List) customerPoList);
                }
                return null;
            }

            @Override
            public  T mapSearchHit(SearchHit searchHit, Class aClass) {
                return null;
            }
        });
        System.out.println("总页数:"+customerPos.getTotalPages());
        System.out.println("总记录数:"+customerPos.getTotalElements());
        List customerPoList = customerPos.getContent();
        for (CustomerPo customerPo:customerPoList) {
            System.out.println(customerPo.toString());

        }
        return "查询完成";
    }

5. Springboot对ES文档进行数据排序

只需要加入排序的构建就ok了

    @GetMapping("/list")
    @ResponseBody
    public String getList(){
        //4.加入排序构建
        SortBuilder sortBuilder1 = new FieldSortBuilder("consume")
                .order(SortOrder.DESC);
        SortBuilder sortBuilder2 = new FieldSortBuilder("age")
                .order(SortOrder.ASC);

        //3.定义分页
        Pageable pageable = PageRequest.of(0,6);
        //2.定义query对象
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("desc","学习"))
                .withPageable(pageable)
                .withSort(sortBuilder1)
                .withSort(sortBuilder2)
                .build();
        //1.先写查询
        AggregatedPage customerPos = elasticsearchTemplate.queryForPage(query,CustomerPo.class);
        System.out.println("总页数:"+customerPos.getTotalPages());
        System.out.println("总记录数:"+customerPos.getTotalElements());
        List customerPoList = customerPos.getContent();
        for (CustomerPo customerPo:customerPoList) {
            System.out.println(customerPo.toString());

        }
        return "查询完成";
    }

不要以为每天把功能完成了就行了,这种思想是要不得的,互勉~!

你可能感兴趣的:(Elasticsearch springboot整合ES)