当前位置:   article > 正文

SpringBoot集成ES

SpringBoot集成ES

java代码使用ES

依赖:
<!--es的包-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
ElasticsearchRepository接口:

创建一个接口,继承ElasticsearchRepository,即可使用注解注入

/**
 * ElasticsearchRepository接口
 */
@Repository
public interface CourseElasticsearchRepository extends ElasticsearchRepository<SearchCourseDoc, Long> {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
高亮、聚合工具类:
import com.alibaba.fastjson.JSON;
import net.minidev.json.JSONObject;
import org.assertj.core.util.Lists;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
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.stereotype.Component;
import java.util.List;
import java.util.Map;

@Component
public class HighlightResultMapper implements SearchResultMapper {

    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
        // 记录总条数
        long totalHits = response.getHits().getTotalHits();
        // 记录列表(泛型) - 构建Aggregate使用
        List<T> list = Lists.newArrayList();
        // 获取搜索结果(真正的的记录)
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits) {
            if (hits.getHits().length <= 0) {
                return null;
            }
            // 将原本的JSON对象转换成Map对象
            Map<String, Object> map = hit.getSourceAsMap();
            // 获取高亮的字段Map
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            for (Map.Entry<String, HighlightField> highlightField : highlightFields.entrySet()) {
                // 获取高亮的Key
                String key = highlightField.getKey();
                // 获取高亮的Value     <b sytype>娃娃</b>
                HighlightField value = highlightField.getValue();
                // 实际fragments[0]就是高亮的结果,无需遍历拼接
                Text[] fragments = value.getFragments();
                StringBuilder sb = new StringBuilder();
                for (Text text : fragments) {
                    sb.append(text);
                }
                // 因为高亮的字段必然存在于Map中,就是key值
                // 可能有一种情况,就是高亮的字段是嵌套Map,也就是说在Map里面还有Map的这种情况,这里没有考虑
                map.put(key, sb.toString());
            }
            // 把Map转换成对象  fastjson
            T item = JSON.parseObject(JSONObject.toJSONString(map), aClass);
            list.add(item);
        }
        // 返回的是带分页的结果。response.getAggregations()为聚合返回的数据
        return new AggregatedPageImpl<>(list, pageable, totalHits, response.getAggregations());
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
数据操作CRUD:
import cn.lin.doc.PageListSearch;
import cn.lin.doc.SearchCourseDoc;
import cn.lin.domain.AggregationParam;
import cn.lin.mapper.HighlightResultMapper;
import cn.lin.query.CourseQuery;
import cn.lin.repository.CourseElasticsearchRepository;
import cn.lin.util.AjaxResult;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
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.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;

public class SearchCourseToES {

    //创建索引
    @Autowired
    private ElasticsearchTemplate template;

    //具体操作
    @Autowired
    private CourseElasticsearchRepository repository;

    //高亮、聚合映射
    @Autowired
    private HighlightResultMapper highlightResultMapper;

    /**
     * 保存信息到ES
     *
     * @param courseDoc
     * @return
     */
    @RequestMapping("/course/save")
    public AjaxResult saveCourse(@RequestBody SearchCourseDoc courseDoc) {
        repository.save(courseDoc);
        return new AjaxResult();
    }

	/**
     * 删除
     */
    @RequestMapping("/course/del")
    public AjaxResult testDelete() {
        //执行删除
        repository.deleteById(1L);
        return new AjaxResult();
    }

    /**
     * 排序方式
     *
     * @param sort
     * @return
     */
    public SortOrder sortType(String sort) {
        if (sort.equals("desc")) {
            return SortOrder.DESC;
        } else {
            return SortOrder.ASC;
        }
    }

    /**
     * 排序编号
     *
     * @param sn
     * @return
     */
    public String sortField(String sn) {
        switch (sn) {
            case "rq":
                return "viewCount";
            case "xp":
                return "onLine";
            case "pl":
                return "commentCount";
            case "jg":
                return "price";
            default:
                return "saleCount";
        }
    }

    /**
     * 查询ES展示数据
     *
     * @param queryParams
     * @return
     */
    @PostMapping("/queryCourses")
    public AjaxResult queryCourses(@RequestBody CourseQuery queryParams) {

        //创建NativeSearchQueryBuilder对象
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();

        //排序、查询条件
        BoolQueryBuilder boolQuery = getBoolQueryBuilder(queryParams, builder);

        //高亮,创建HighlightBuilder对象,添加高亮显示字段与高亮显示标签
        HighlightBuilder.Field field = new HighlightBuilder.Field("name").preTags("<font style='color:red'>").postTags("</font>");
        //高亮设置,添加至NativeSearchQueryBuilder查询器
        builder.withHighlightFields(field);

        /*
         * 聚合查询,创建聚合条件
         * terms: 给这个聚合起个名
         * field:要对哪个字段聚合
         */
        TermsAggregationBuilder aggreTenantName = AggregationBuilders.terms("organizationAggreTenantName").field("tenantName"). //对机构名进行聚合
                size(10).order(Terms.Order.count(false));
        TermsAggregationBuilder aggreGradeName = AggregationBuilders.terms("organizationAggreGradeName").field("gradeName"). //对类型进行聚合
                size(10).order(Terms.Order.count(false)); //只获取前十条数据,根据数据量排序

        //聚合条件加入
        builder.addAggregation(aggreTenantName);
        builder.addAggregation(aggreGradeName);

        //查询
        builder.withQuery(boolQuery);
        NativeSearchQuery build = builder.build();

        /*
         * 获取数据
         * 高亮、聚合查询,需要使用template.queryForPage()
         */
        AggregatedPage<SearchCourseDoc> page = template.queryForPage(build, SearchCourseDoc.class, highlightResultMapper);
//        Page<SearchCourseDoc> page = repository.search(build);

        //聚合结果取值
        StringTerms organizationAggreTenantName = (StringTerms) page.getAggregation("organizationAggreTenantName");
        //获取聚合对象
        List<StringTerms.Bucket> bucketsTenantName = organizationAggreTenantName.getBuckets();
        List<AggregationParam> listTenantName = new ArrayList<>();
        //遍历,存值
        bucketsTenantName.forEach(bucket -> listTenantName.add( new AggregationParam(String.valueOf(bucket.getKey()), bucket.getDocCount())));

        //聚合取值
        StringTerms organizationAggreGradeName = (StringTerms) page.getAggregation("organizationAggreGradeName");
        //聚合对象取值
        List<StringTerms.Bucket> bucketsGradeName = organizationAggreGradeName.getBuckets();
        List<AggregationParam> listGradeName = new ArrayList<>();
        //遍历,存值
        bucketsGradeName.forEach(bucket -> listGradeName.add( new AggregationParam(String.valueOf(bucket.getKey()), bucket.getDocCount())));

        //返回对象
        PageListSearch resultObj = new PageListSearch(page.getTotalElements(), page.getContent(),listTenantName,listGradeName);
        return new AjaxResult().setResultObj(resultObj);

    }

    /**
     * 查询条件
     * @param queryParams
     * @param builder
     * @return
     */
    private BoolQueryBuilder getBoolQueryBuilder(CourseQuery queryParams, NativeSearchQueryBuilder builder) {
        //排序
        builder.withSort(SortBuilders.fieldSort(sortField(queryParams.getSortField())).order(sortType(queryParams.getSortType())));
        //分页
        builder.withPageable(PageRequest.of(queryParams.getPage()-1, queryParams.getRows()));

        //创建查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //加入条件
        if (StringUtils.hasLength(queryParams.getKeyword())) {
            boolQuery.must(QueryBuilders.matchQuery("name", queryParams.getKeyword()));
        }
        //价格
        if (queryParams.getPriceMin() != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(queryParams.getPriceMin()));
        }
        if (queryParams.getPriceMax() != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(queryParams.getPriceMax()));
        }
        if (queryParams.getCourseTypeId() != null) {
            boolQuery.filter(QueryBuilders.termQuery("courseTypeId", queryParams.getCourseTypeId()));
        }
        if (queryParams.getCourseTypeName() != null) {
            boolQuery.filter(QueryBuilders.termQuery("gradeName", queryParams.getCourseTypeName()));
        }
        if (queryParams.getTenantName() != null) {
            boolQuery.filter(QueryBuilders.termQuery("tenantName", queryParams.getTenantName()));
        }
        return boolQuery;
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/469342
推荐阅读
相关标签
  

闽ICP备14008679号