• es的高亮查询


    1.导入配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
        <!-- 扫描Dao包,自动创建实例,制定一个es仓库的包扫描位置 -->
        <!-- 主要是用spring-data的方式来操作es的增删改查 -->
        <!-- 这个包下就是我们声明的es仓库的接口 -->
        <elasticsearch:repositories base-package="com.liujin.cms.dao" />
        <!-- es提供了2个端口号:9200和9300
            9200:对浏览器暴露的端口号
            9300:是对java编程需要操作es所暴露的端口号
         -->
         <!-- 指定es的IP地址和端口号    通过浏览器发送restful请求,就能够实现es的crud-->
        <elasticsearch:transport-client id="client"
            cluster-nodes="192.168.26.130:9300" /> <!-- spring data elasticSearcheDao 必须继承 ElasticsearchTemplate -->
            
            <!-- 声明一个对象,叫elasticsearchTemplate  就是负责es的CRUD的操作 -->
        <bean id="elasticsearchTemplate"
            class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
            <constructor-arg name="client" ref="client"></constructor-arg>
        </bean>
        
    </beans>

    2.在所要检索的实体类下加入注解

    //指定了库名、表名(库名必须用纯小写,不能有特殊字符)

    @Document(indexName = "zhunneng",type = "plan")
    public class Plan implements Serializable{

    //指定id

    @Id

    private int id;

    //指定name字段的值是否索引,是否存储          分词方式                                           搜索的关键字分词的方式                              指定数据类型
    @Field(index = true,store = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word",type = FieldType.text)
    private String name;
    private double amount;
    @Field(index = true,store = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word",type = FieldType.text)
    private String manager;
    @Field(index = true,store = true,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word",type = FieldType.text)
    private String content;
    private Dept dept;

    3.在dao层下写入抽象类继承接口ElasticsearchRepository

    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    import com.liujin.cms.domain.Plan;
    ////当你的接口继承了这个接口之后,就自动具备了crud的功能          1.指定要操作的实体类  2.实体类主键类型
    public interface PlanRepository extends ElasticsearchRepository<Plan, Integer>{ }

    4.导入工具类

    /**   
     * Copyright © 2019 公司名. All rights reserved.
     * 
     * @Title: ESUtils.java 
     * @Prject: chengongjun_cms
     * @Package: com.chengongjun.chengongjun_cms.utils 
     * @Description: TODO
     * @author: chj   
     * @date: 2019年7月24日 上午10:14:13 
     * @version: V1.0   
     */
    package com.liujin.cms.util;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.index.query.QueryBuilder;
    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.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    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.GetQuery;
    import org.springframework.data.elasticsearch.core.query.IndexQuery;
    import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    import org.springframework.data.elasticsearch.core.query.SearchQuery;
    
    import com.github.pagehelper.PageInfo;
    
    
    /**
     * @ClassName: ESUtils
     * @Description: TODO
     * @author: 
     * @date: 2019年7月24日 上午10:14:13
     */
    public class HLUtils {
    
    
        /**
         * 保存及更新方法
         * 
         * @param elasticsearchTemplate
         * @param id
         * @param object
         */
        public static void saveObject(ElasticsearchTemplate elasticsearchTemplate, String id, Object object) {
            // 创建所以对象
            IndexQuery query = new IndexQueryBuilder().withId(id).withObject(object).build();
            // 建立索引
            elasticsearchTemplate.index(query);
        }
    
        /**
         * 批量删除
         * 
         * @param elasticsearchTemplate
         * @param clazz
         * @param ids
         */
        public static void deleteObject(ElasticsearchTemplate elasticsearchTemplate, Class<?> clazz, Integer ids[]) {
            for (Integer id : ids) {
                // 建立索引
                elasticsearchTemplate.delete(clazz, id + "");
            }
        }
    
        /**
         * 
         * @Title: selectById
         * @Description: 根据id在es服务启中查询对象
         * @param elasticsearchTemplate
         * @param clazz
         * @param id
         * @return
         * @return: Object
         */
        public static Object selectById(ElasticsearchTemplate elasticsearchTemplate, Class<?> clazz, Integer id) {
            GetQuery query = new GetQuery();
            query.setId(id + "");
            return elasticsearchTemplate.queryForObject(query, clazz);
        }
        //当你的接口继承了这个接口之后,就自动具备了crud的功能                                  1.指定要操作的实体类  2.实体类主键类型
        //public interface UserRespository extends ElasticsearchCrudRepository<User, Integer>
        //指定了库名、表名(库名必须用纯小写,不能有特殊字符)
        //@Document(indexName = "test_user",type = "user")
        //指定name字段的值是否索引,是否存储          分词方式                                           搜索的关键字分词的方式                              指定数据类型
        //@Field(index = true,store = true,analyzer = "ik_smart",searchAnalyzer ="ik_smart",type = FieldType.text )
        // 查询操作
        //HLUtils.findByHighLight(elasticsearchTemplate, CompanyAnnualCheck.class, pageNum, pageSize, new String[] {"keywords","companyName"}, "id", key);
        public static PageInfo<?> findByHighLight(ElasticsearchTemplate elasticsearchTemplate, Class<?> clazz, Integer page,
                Integer rows, String fieldNames[],String sortField, String value) {
            AggregatedPage<?> pageInfo = null;
            PageInfo<?> pi = new PageInfo<>();
            // 创建Pageable对象                                                        主键的实体类属性名
            final Pageable pageable = PageRequest.of(page - 1, rows, Sort.by(Sort.Direction.ASC, sortField));
            //查询对象
            SearchQuery query = null;
            //查询条件高亮的构建对象
            QueryBuilder queryBuilder = null;
            
            if (value != null && !"".equals(value)) {
                // 高亮拼接的前缀与后缀
                String preTags = "<font color="red">";
                String postTags = "</font>";
    
                // 定义创建高亮的构建集合对象
                HighlightBuilder.Field highlightFields[] = new HighlightBuilder.Field[fieldNames.length];
    
                for (int i = 0; i < fieldNames.length; i++) {
                    // 这个代码有问题
                    highlightFields[i] = new HighlightBuilder.Field(fieldNames[i]).preTags(preTags).postTags(postTags);
                }
    
                // 创建queryBuilder对象
                queryBuilder = QueryBuilders.multiMatchQuery(value, fieldNames);
                query = new NativeSearchQueryBuilder().withQuery(queryBuilder).withHighlightFields(highlightFields)
                        .withPageable(pageable).build();
    
                pageInfo = elasticsearchTemplate.queryForPage(query, clazz, new SearchResultMapper() {
    
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable1) {
    
                        List<T> content = new ArrayList<T>();
                        long total = 0l;
    
                        try {
                            // 查询结果
                            SearchHits hits = response.getHits();
                            if (hits != null) {
                                //获取总记录数
                                total = hits.getTotalHits();
                                // 获取结果数组
                                SearchHit[] searchHits = hits.getHits();
                                // 判断结果
                                if (searchHits != null && searchHits.length > 0) {
                                    // 遍历结果
                                    for (int i = 0; i < searchHits.length; i++) {
                                        // 对象值
                                        T entity = clazz.newInstance();
    
                                        // 获取具体的结果
                                        SearchHit searchHit = searchHits[i]; 
    
                                        // 获取对象的所有的字段
                                        Field[] fields = clazz.getDeclaredFields();
    
                                        // 遍历字段对象
                                        for (int k = 0; k < fields.length; k++) {
                                            // 获取字段对象
                                            Field field = fields[k];
                                            // 暴力反射
                                            field.setAccessible(true);
                                            // 字段名称
                                            String fieldName = field.getName();
                                            if (!fieldName.equals("serialVersionUID")&&!fieldName.equals("user")&&!fieldName.equals("channel")&&!fieldName.equals("category")&&!fieldName.equals("articleType")&&!fieldName.equals("imgList")) {
                                                HighlightField highlightField = searchHit.getHighlightFields()
                                                        .get(fieldName);
                                                if (highlightField != null) {
                                                    // 高亮 处理 拿到 被<font color='red'> </font>结束所包围的内容部分
                                                    String value = highlightField.getFragments()[0].toString();
                                                    // 注意一下他是否是 string类型
                                                    field.set(entity, value);
                                                } else {
                                                    //获取某个字段对应的 value值
                                                    Object value = searchHit.getSourceAsMap().get(fieldName);
                                                    // 获取字段的类型
                                                    Class<?> type = field.getType();
                                                    if (type == Date.class) {
                                                        // bug
                                                        if(value!=null) {
                                                            field.set(entity, new Date(Long.valueOf(value + "")));
                                                        }
                                                    } else {
                                                        field.set(entity, value);
                                                    }
                                                }
                                            }
                                        }
    
                                        content.add(entity);
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
    
                        return new AggregatedPageImpl<T>(content, pageable, total);
                    }
                });
    
            } else {
                // 没有查询条件的的时候,获取es中的全部数据 分页获取
                query = new NativeSearchQueryBuilder().withPageable(pageable).build();
                pageInfo = elasticsearchTemplate.queryForPage(query, clazz);
            }
            int totalCount = (int) pageInfo.getTotalElements();
            int pages = totalCount%rows==0?totalCount/rows:totalCount/rows+1;
            pi.setTotal(pageInfo.getTotalElements());
            pi.setPageNum(page);
            pi.setPageSize(rows);
            pi.setPrePage(page-1);
            pi.setLastPage(page+1);
            pi.setPages(pages);
            List content = pageInfo.getContent();
            pi.setList(content);
    
            return pi;
        }
    
    }

    5.在controller下调用工具类中的高亮查询的方法

    // 查询操作
        //HLUtils.findByHighLight(elasticsearchTemplate, CompanyAnnualCheck.class, pageNum, pageSize, new String[] {"keywords","companyName"}, "id", key);
  • 相关阅读:
    为什么使用指针比使用对象本身更好?
    基于回调的事件处理——基于回调的事件传播
    基于回调的事件处理——回调机制与监听机制
    基于监听的事件处理——直接绑定到标签
    基于监听的事件处理——匿名内部类作为事件监听器类
    基于监听的事件处理——Activity本身作为事件监听器
    基于监听的事件处理——外部类作为事件监听器类
    基于监听的事件处理——内部类作为事件监听器类
    基于监听的事件处理——事件和事件监听器
    基于监听的事件处理——监听的处理模型
  • 原文地址:https://www.cnblogs.com/liujinqq7/p/12693708.html
Copyright © 2020-2023  润新知