Spring Boot2.X整合ElasticSearch6.X示例

介绍(官网翻译)

用于Elasticsearch的Spring Data是Spring Data项目的一部分,该项目旨在为新数据存储提供熟悉且一致的基于Spring的编程模型,同时保留特定于存储的功能。

Spring Data Elasticsearch项目提供了与Elasticsearch搜索引擎的集成。Spring Data Elasticsearch的关键功能区域是一个以POJO为中心的模型,该模型用于与Elastichsearch文档进行交互并轻松编写存储库样式的数据访问层。

官方文档: https://spring.io/projects/spring-data-elasticsearch

特征(官网翻译)

  • Spring配置支持使用基于Java的@Configuration类或ES客户端实例的XML名称空间。
  • ElasticsearchTemplate帮助程序类,可提高执行常规ES操作的效率。包括文档和POJO之间的集成对象映射。
  • 与Spring的转换服务集成的功能丰富的对象映射
  • 基于注释的映射元数据,但可扩展以支持其他元数据格式
  • Repository接口的自动实现,包括对自定义查找器方法的支持。
  • CDI对存储库的支持

版本

spring-boot:2.1.6.RELEASE
jdk:1.8
elasticsearch:6.6.2

pom.xml

<!-- 集成elasticsearch -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

application.properties

# ############# elasticsearch set ################
# 参见elasticsearch-x.x/config/elasticsearch.yml
spring.data.elasticsearch.cluster-name=my-application
# 多个用逗号隔开,9300作为Tcp协议,用于jar包开发
spring.data.elasticsearch.cluster-nodes=192.168.110.35:9300

Message.java

package com.pro.tools.elasticsearch.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import javax.persistence.Id;
import java.util.Date;
/**
 * @Description 索引文档对象(结构)
 * @Version V1.0
 */
@Data//data:自动生成getter和setter方法
@Accessors(chain = true)//chain:中文含义是链式的,设置为true,则setter方法返回当前对象; 如:public Message setId()
@Document(indexName = "message-test-index", type = "doc") //doc注解,indexName表示索引名,type类型
public class Message {
    /**
     @Document:
     indexName:表示索引名称
     type:类型,类似于表名称
     shards:分片数量,默认为5
     replicas:副本数量,默认为1
    
     @Field:
     type=FieldType.Text,字段类型,表示为字符串,并分词检索;常用类型:text、keyword、date、long、double、boolean和ip
     index=true,表示是否索引
     store=true,表示是否存储
     analyzer="ik_word",表示使用指定分词器
     searchAnalyzer="ik_max_word",表示搜索模式使用指定分词器
    
     补充说明:准确数据类型: keyword,会直接被存储为了二进制,直接比较;全文文本类型: text,按检索出相似度最高低返回;
     */
    /**
     * @Id 表示主键,会自动给索引记录_id赋值
     */
    @Id
    private String id;
    /**
     * FieldType.Date 时间类型
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS")
    @Field(type = FieldType.Date)
    private Date logdate;
    /**
     * FieldType.Text 文本类型
     */
    @Field(type = FieldType.Text)
    private String thread;
    @Field(type = FieldType.Text)
    private String level;
    /**
     * FieldType.Keyword 表示支持分词
     */
    @Field(type = FieldType.Keyword)
    private String msg;
}

1. 基于ElasticsearchRepository的实现操作

MessageRepository.java

package com.pro.tools.elasticsearch.dao;
import com.pro.tools.elasticsearch.vo.Message;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
 * @Description 绑定实体对象进行es操作,ES索引库访问接口
 * @Version V1.0
 */
public interface MessageRepository extends ElasticsearchRepository<Message, String> {
}

MessageService.java

package com.pro.tools.elasticsearch.service;
import com.pro.tools.elasticsearch.dao.MessageRepository;
import com.pro.tools.elasticsearch.vo.Blog;
import com.pro.tools.elasticsearch.vo.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
 * @Description 绑定实体对象进行es操作
 * @Version V1.0
 */
@Service
public class MessageService {
    @Autowired
    private MessageRepository messageRepository;
    public void add(Message message){
        messageRepository.save(message);
    }
    public void update(Message message){
        messageRepository.save(message);
    }
    public Message findById(String id){
        Optional<Message> optional = messageRepository.findById(id);
        if (optional.isPresent()){
            return optional.get();
        }
        return null;
    }
    public void delete(String id){
        messageRepository.deleteById(id);
    }
    public List<Message> findAll(){
        List<Message> messageList = new ArrayList<>();
        Iterable<Message>  messages = messageRepository.findAll();
        if (messages != null){
            messages.forEach(message -> messageList.add(message));
        }
        return messageList;
    }
    public Page<Message> pageList(Message message, int page, int pageSize){
        Pageable pageable = this.order(page,pageSize,"logdate");
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //filter:必需满足过滤的条件
        //精确匹配索引条件
//        queryBuilder.must(QueryBuilders.termQuery("level","INFO"));
        //queryBuilder.must(QueryBuilders.rangeQuery("time").from(100000000L).to(System.currentTimeMillis()));//大于query,小于当前时间
        //模糊匹配索引条件
//        queryBuilder.filter(QueryBuilders.matchQuery("level",message.getLevel()));
        //通配wildcard检索引条件
//        queryBuilder.filter(QueryBuilders.wildcardQuery("msg", "*" +message.getMsg()+ "*"));

        //must:AND组合条件查询
        //模糊匹配索引条件
        queryBuilder.must(QueryBuilders.matchQuery("level",message.getLevel()));
        //短语模糊匹配索引条件
        //queryBuilder.must(QueryBuilders.matchPhraseQuery("msg", "*" +message.getMsg()+ "*"));
        //通配wildcard检索引条件
        queryBuilder.must(QueryBuilders.wildcardQuery("msg", "*" +message.getMsg()+ "*"));

        //should:OR组合条件查询
        //模糊匹配检索引条件
        //queryBuilder.should(QueryBuilders.matchQuery("level",message.getLevel()));
        //通配wildcard检索引条件
        //queryBuilder.should(QueryBuilders.wildcardQuery("msg", "*" +message.getMsg()+ "*"));

        Page<Message> messagePage = messageRepository.search(queryBuilder, pageable);

        //相似度匹配接口,必带id字段
        //Page<Message> messagePage = messageRepository.searchSimilar(message,new String[]{"msg"},pageable);

        //查询所有
        //Page<Message> messagePage = messageRepository.findAll(pageable);
        return messagePage;
    }
    public Pageable order(int page, int pageSize, String properties){
        Sort sort = new Sort(Sort.Direction.DESC,properties);
        return PageRequest.of(page-1,pageSize, sort);
    }
}

MessageController.java

package com.pro.tools.elasticsearch.controller;
import com.alibaba.fastjson.JSON;
import com.pro.tools.elasticsearch.service.MessageService;
import com.pro.tools.elasticsearch.vo.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
/**
 * @Description 基于springboot-elasticsearch的增、删、改、查示例
 * @Version V1.0
 */
@RestController
@RequestMapping("/es/message")
public class MessageController {
    @Autowired
    private MessageService messageService;
    /**
     * 添加Message到索引
     * @return
     */
    @PostMapping(value = "/add")
    public String add(Message message){
        if (message.getLogdate() == null){
            message.setLogdate(new Date());
        }
        messageService.add(message);
        return "ok";
    }
    /**
     * 更新Message到索引
     * @return
     */
    @PostMapping(value = "/update")
    public String update(Message message){
        if (message.getLogdate() == null){
            message.setLogdate(new Date());
        }
        messageService.update(message);
        return "ok";
    }
    /**
     * 删除索引内指定ID
     * @param id
     * @return
     */
    @GetMapping(value = "/delete")
    public String delete(String id){
        messageService.delete(id);
        return "ok";
    }
    /**
     * 查询索引库指定ID
     * @param id
     * @return
     */
    @GetMapping(value = "/findById")
    @ResponseBody
    public Object findById(String id){
        return messageService.findById(id);
    }
    /**
     * 获取索引库所有文档
     * @return
     */
    @GetMapping(value = "/list")
    public Object list(){
        return messageService.findAll();
    }
    /**
     * 分页获取索引库文档列表
     * @return
     */
    @GetMapping(value = "/pageList")
    public Object pageList(Message message, @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){
        return messageService.pageList(message,page==null?1:page,pageSize==null?10:pageSize);
    }
}

2.基于springboot中elasticsearchTemplate模板对象操作示例

TemplateController.java

package com.pro.tools.elasticsearch.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pro.tools.elasticsearch.service.TemplateService;
import com.pro.tools.elasticsearch.vo.Message;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
 * @Description 基于elasticsearchTemplate的增、删、改、查示例
 * @Version V1.0
 */
@RestController
@RequestMapping("/es/template")
public class TemplateController {
    @Autowired
    private TemplateService templateService;
    @GetMapping(value = "/createIndex")
    public String createIndex(String indexName){
        templateService.createIndex(indexName);
        return "ok";
    }
    @GetMapping(value = "/deleteIndex")
    public String deleteIndex(String indexName){
        templateService.deleteIndex(indexName);
        return "ok";
    }
    @GetMapping(value = "/indexExists")
    public String indexExists(String indexName){
        templateService.indexExists(indexName);
        return "ok";
    }
    @GetMapping(value = "/addDoc")
    public String addDoc(@RequestParam("indexName") String indexName, Message message){
        if (message.getLogdate() == null){
            message.setLogdate(new Date());
        }
        templateService.addDoc(indexName, message);
        return "ok";
    }
    @GetMapping(value = "/deleteDoc")
    public String deleteDoc(String indexName, String id){
        templateService.deleteDoc(indexName, id);
        return "ok";
    }
    @PostMapping(value = "/updateDoc")
    public String updateDoc(@RequestParam("indexName") String indexName, Message message){
        templateService.updateDoc(indexName, message);
        return "ok";
    }
    @PostMapping(value = "/bulkUpdate")
    public String bulkUpdate(@RequestBody JSONObject jsonObject){
        String indexName = jsonObject.getString("indexName");
        JSONArray jsonArray = jsonObject.getJSONArray("messageList");
        List<Message> messageList = jsonArray.toJavaList(Message.class);
        templateService.bulkUpdate(indexName, messageList);
        return "ok";
    }
    @GetMapping(value = "/queryById")
    @ResponseBody
    public Object queryById(String id){
        return templateService.queryById(id);
    }
    @GetMapping(value = "/queryAlias")
    @ResponseBody
    public Object queryAlias(String indexName){
        return templateService.queryAlias(indexName);
    }
    @GetMapping(value = "/findById")
    @ResponseBody
    public Object findById(String id){
        return templateService.findById(id);
    }
    @GetMapping(value = "/deleteById")
    public String deleteById(String id){
        templateService.deleteById(id);
        return "ok";
    }
    @GetMapping(value = "/count")
    public String count(String level){
        if(StringUtils.isNotBlank(level)){
            return templateService.count(level) + "";
        }else {
            return templateService.count() + "";
        }
    }
    @GetMapping(value = "/highlightQuery")
    @ResponseBody
    public Object highlightQuery(String level){
        return templateService.highlightQuery(level);
    }
    @PostMapping(value = "/highlightQueryObject")
    @ResponseBody
    public Object highlightQueryObject(Message message){
        return templateService.highlightQuery(message);
    }
    @PostMapping(value = "/queryPage")
    @ResponseBody
    public Object queryPage(Message message, @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){
        return templateService.queryPage(message, page==null?1:page, pageSize==null?10:pageSize);
    }
}

TemplateService.java

package com.pro.tools.elasticsearch.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.pro.tools.elasticsearch.vo.Message;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description 使用spring内置的elasticsearchTemplate组件对es操作
 * @Version V1.0
 */
@Service
public class TemplateService {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 创建索引
     * @param indexName
     */
    public boolean createIndex(String indexName){
        return elasticsearchTemplate.createIndex(indexName);
    }

    /**
     * 提交字段映射结构
     */
    public boolean putMapping(){
        return elasticsearchTemplate.putMapping(Message.class);
    }

    /**
     * 删除索引
     * @param indexName
     */
    public boolean deleteIndex(String indexName){
        return elasticsearchTemplate.deleteIndex(indexName);
    }

    /**
     * 判断索引是否存在
     * @param indexName
     * @return
     */
    public boolean indexExists(String indexName){
        return elasticsearchTemplate.indexExists(indexName);
    }

    /**
     * 添加文档对象到指定索引
     * @param indexName
     * @param message
     */
    public void addDoc(String indexName, Message message){
        this.addDoc(indexName,"doc",message.getId(), JSON.toJSONString(message));
    }

    /**
     * 添加文档对象到指定索引
     * @param indexName
     * @param type
     * @param id
     * @param jsonDoc
     */
    public void addDoc(String indexName, String type,String id,String jsonDoc){
        //添加索引文档
        IndexQuery indexQuery = new IndexQueryBuilder()
                .withIndexName(indexName)
                .withType(type)
                .withId(id)
                .withSource(jsonDoc)
                .build();
        elasticsearchTemplate.index(indexQuery);
        //刷新索引
        elasticsearchTemplate.refresh(indexName);
    }

    /**
     * 删除索引下指定ID文档
     * @param indexName
     * @param id
     */
    public void deleteDoc(String indexName, String id){
        //elasticsearch6.0以上版本后,取消了type的定义关系,但会保留_type字段,默认值并且为doc,官方建议一个索引库就是一张表,而不是通过type字段去映射不同的表字段组合所表示的表名称;
        this.deleteDoc(indexName,"doc", id);
    }

    /**
     * 删除索引下指定ID文档
     * @param indexName
     * @param type
     * @param id
     */
    public void deleteDoc(String indexName,String type, String id){
        elasticsearchTemplate.delete(indexName, type, id);
    }

    /**
     * 更新索引下的文档对象
     * @param indexName
     * @param message
     */
    public void updateDoc(String indexName, Message message){
        this.updateDoc(indexName,"doc", message.getId(), message);
    }

    /**
     * 更新索引下的文档对象
     * @param indexName
     * @param type
     * @param id
     * @param mssage
     */
    public void updateDoc(String indexName, String type,String id,Message mssage){
        this.updateDoc(indexName, type, id, JSON.toJSONString(mssage));
    }

    /**
     * 更新索引下的文档对象
     * @param indexName
     * @param type
     * @param id
     * @param jsonDoc
     */
    public void updateDoc(String indexName, String type,String id,String jsonDoc){
        UpdateQuery query = this.createUpdateQuery(indexName, type, id, jsonDoc);
        elasticsearchTemplate.update(query);
    }

    /**
     * 创建更新对象
     * @param indexName
     * @param type
     * @param id
     * @param jsonDoc
     * @return
     */
    private UpdateQuery createUpdateQuery(String indexName, String type,String id,String jsonDoc){
        UpdateQuery query = new UpdateQuery();
        query.setIndexName(indexName);
        query.setId(id);
        query.setType(type);
        query.setDoUpsert(true);
        UpdateRequest updateRequest = new UpdateRequest(indexName,type,id);
        updateRequest.doc(jsonDoc, XContentType.JSON);
        query.setUpdateRequest(updateRequest);
        return query;
    }

    /**
     * 批量更新
     * @param indexName
     * @param messageList
     */
    public void bulkUpdate(String indexName, List<Message> messageList){
        List<UpdateQuery> updateQueryList = new ArrayList<>();
        for (Message message : messageList){
            UpdateQuery updateQuery = this.createUpdateQuery(indexName, "doc", message.getId(), JSON.toJSONString(message));
            updateQueryList.add(updateQuery);
        }
        this.bulkUpdate(updateQueryList);
    }

    /**
     * 批量更新
     * @param updateQueryList
     */
    public void bulkUpdate(List<UpdateQuery> updateQueryList){
        elasticsearchTemplate.bulkUpdate(updateQueryList);
    }

    /**
     * 通过ID查询指定DOC文档
     * @param id
     * @return
     */
    public List<Message> queryById(String id){
        NativeSearchQueryBuilder mqb = new NativeSearchQueryBuilder();
        //建立查询条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //must:AND组合条件查询
        //模糊匹配索引条件
        queryBuilder.must(QueryBuilders.matchQuery("id",id));
        //通配wildcard检索引条件
        mqb.withQuery(queryBuilder);
        //只获取指定字段
        mqb.withFields("id","level","msg");
        //排序字段
        SortBuilder sortBuilder = SortBuilders.fieldSort("logdate");
        sortBuilder.order(SortOrder.ASC);
        mqb.withSort(sortBuilder);
        //查询
        SearchQuery searchQuery = mqb.build();
        return elasticsearchTemplate.queryForList(searchQuery,Message.class);
    }

    public List<AliasMetaData> queryAlias(String indexName) {
        return elasticsearchTemplate.queryForAlias(indexName);
    }

    /**
     * 返回指定字段的高亮结果集
     * @param level
     * @return
     */
    public AggregatedPage<Message> highlightQuery(String level){
        NativeSearchQueryBuilder mqb = new NativeSearchQueryBuilder();
        String highlightField = "level";
        HighlightBuilder.Field field = new HighlightBuilder.Field(highlightField);
        //termQuery表示精确匹配,如果匹本不了,可以加上"filed.keyword"
        //matchPhraseQuery表示精确字段查询
        //matchQuery表示相关度查询使用(请优先使用该方法查询,该方法是核心查询方法,也是底层拼装查询条件方法)
        mqb.withQuery(QueryBuilders.matchPhraseQuery(highlightField, level));
        //设置高亮查询样式
        mqb.withHighlightBuilder(getHighlightBuilder());
        //设置高亮查询字段
        mqb.withHighlightFields(field);
        //查询
        SearchQuery searchQuery = mqb.build();
        SearchResultMapper resultMapper = new MySearchResultMapper(highlightField);
        return elasticsearchTemplate.queryForPage(searchQuery, Message.class, resultMapper);
    }

    /**
     * 分页查询
     * @param message
     * @return
     */
    public AggregatedPage<Message> queryPage(Message message, int page, int pageSize){
        Pageable pageable = PageRequest.of(page, pageSize);
        return this.highlightQuery(message, true, pageable);
    }

    /**
     * 返回高亮结果集
     * @param message
     * @return
     */
    public AggregatedPage<Message> highlightQuery(Message message){
        return this.highlightQuery(message, true, null);
    }

    /**
     * 返回高亮结果集
     * @param message
     * @return
     */
    public AggregatedPage<Message> highlightQuery(Message message, boolean isHighlight, Pageable pageable){
        NativeSearchQueryBuilder mqb;
        String highlightField = "msg";
        //termQuery表示精确匹配,如果匹本不了,可以加上"filed.keyword"
        //matchPhraseQuery表示精确字段查询
        //matchQuery表示相关度查询使用(请优先使用该方法查询,该方法是核心查询方法,也是底层拼装查询条件方法)
        try {
            mqb = this.getQueryBuilder(message);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
        if (isHighlight) {
            //设置高亮查询样式
            mqb.withHighlightBuilder(getHighlightBuilder());
            //设置高亮查询字段
            mqb.withHighlightFields(new HighlightBuilder.Field(highlightField));
        }
        //设置分页
        if (pageable != null){
            mqb.withPageable(pageable);
        }
        //查询
        SearchQuery searchQuery = mqb.build();
        SearchResultMapper resultMapper = new MySearchResultMapper(highlightField);
        return elasticsearchTemplate.queryForPage(searchQuery, Message.class, resultMapper);
    }

    private HighlightBuilder getHighlightBuilder(){
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        return highlightBuilder.preTags("<red>").postTags("</red>");
    }

    /**
     * 设置对象的组件查询条件,返回QueryBuilder实现类对象
     * @param clzss
     * @return
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    private NativeSearchQueryBuilder getQueryBuilder(Object clzss) throws SecurityException, IllegalArgumentException, IllegalAccessException{
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        if (clzss != null){
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            java.lang.reflect.Field [] fs = clzss.getClass().getDeclaredFields();
            for (Field field : fs){
                //设置属性可达
                field.setAccessible(true);
                boolean isKeyword = false;
                //获取名称和值
                String name = field.getName();
                Object value = field.get(clzss);
                //自定义注解
                org.springframework.data.elasticsearch.annotations.Field annField =
                        field.getAnnotation(org.springframework.data.elasticsearch.annotations.Field.class);
                if (annField != null){
                    org.springframework.data.elasticsearch.annotations.FieldType fieldType =annField.type();
                    if (org.springframework.data.elasticsearch.annotations.FieldType.Keyword == fieldType){
                        isKeyword = true;
                    }
                }
                field.setAccessible(false);
                if (value != null) {
                    if (isKeyword){
                        //must表示组合,模糊查询
                        boolQueryBuilder.must(QueryBuilders.wildcardQuery(name, "*"+ value + "*"));
                    }else {
                        //词匹配
                        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(name, value));
                    }
                }
            }
            return queryBuilder.withQuery(boolQueryBuilder);
        }
        return queryBuilder;
    }

    /**
     * 按ID查询对象所在索引库数据
     * @param id
     * @return
     */
    public Message findById(String id) {
        GetQuery getQuery = new GetQuery();
        getQuery.setId(id);
        return elasticsearchTemplate.queryForObject(getQuery, Message.class);
    }

    /**
     * 按ID删除对象所在索引库数据
     * @param id
     */
    public void deleteById(String id){
        elasticsearchTemplate.delete(Message.class, id);
    }

    /**
     * 统计全库大小
     * @return
     */
    public long count(){
        SearchQuery query = new NativeSearchQueryBuilder().build();
        return elasticsearchTemplate.count(query,Message.class);
    }

    /**
     * 统计指定字段命中的数据大小
     * @param level
     * @return
     */
    public long count(String level){
        NativeSearchQueryBuilder mqb = new NativeSearchQueryBuilder();
        mqb.withQuery(QueryBuilders.matchQuery("level",level));
        SearchQuery query = mqb.build();
        return elasticsearchTemplate.count(query,Message.class);
    }

    /**
     * 自定义返回结果集解析类,如:高亮处理
     */
    class MySearchResultMapper implements SearchResultMapper {
        /**
         * 高亮字段
         */
        private String highlightField;
        public MySearchResultMapper(String highlightField){
            this.highlightField = highlightField;
        }

        /**
         * 结果集回写方法
         * @param response
         * @param clazz
         * @param pageable
         * @param <T>
         * @return
         */
        @Override
        public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
            SearchHits hits = response.getHits();
            if (hits.totalHits <=  0){
                return null;
            }
            List<Message> messageList = new ArrayList<>();
            for (SearchHit hit : hits){
                Map<String,Object> asMap = hit.getSourceAsMap();
                if (CollectionUtils.isEmpty(asMap)){
                    continue;
                }
                Message message = JSON.toJavaObject((JSONObject)JSON.toJSON(asMap), Message.class);
                messageList.add(message);
                //加载高亮字段
                if (StringUtils.isNotBlank(highlightField)){
                    Map<String,HighlightField> highlightFieldMap = hit.getHighlightFields();
                    if (!CollectionUtils.isEmpty(highlightFieldMap)){
                        HighlightField highlight = highlightFieldMap.get(highlightField);
                        if (highlight != null && highlight.getFragments() != null) {
                            message.setMsg(highlight.getFragments()[0].toString());
                        }
                    }
                }
            }
            AggregatedPage page = new AggregatedPageImpl<>(messageList);
            return page;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值