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);