elasticsearch使用template搜索多个索引并且高亮返回结果

由于搜索多个索引没办法以定义好的Entity来接收quey的结果,所以keyword搜索时不能按照以前的方式来直接分页搜索

AggregatedPage<ElasticService> elasticServices = elasticsearchTemplate.queryForPage(nativeSearchQuery, ElasticService.class);

所以这里选择重写搜索方法来自定义map返回结果,实现手动分页和替换高亮搜索的结果

		Pageable pageable = PageRequest.of(pageNum, pageSize, Sort.Direction.DESC, "update_time");
        // 关键字可在name字段进行通配符搜索
        QueryBuilder nameWildcardNameQuery = QueryBuilders.wildcardQuery("name", "*" + keywords + "*");
        QueryBuilder categoryNameWildcardNameQuery = QueryBuilders.wildcardQuery("categoryName", "*" + keywords + "*");
        // name字段boost提高,从而match之后提高得分
        Map<String, Float> fieldMap = new HashMap<>();
        fieldMap.put("name", 5.0f);
        fieldMap.put("categoryName", 4.5f);
        fieldMap.put("namespace", 1.0f);
        fieldMap.put("description", 0.5f);
        QueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(keywords).fields(fieldMap);
        // should不会影响搜索结果,但match多了可提高得分
       QueryBuilder keywordMatchQuery = QueryBuilders.boolQuery().should(nameWildcardNameQuery).should(categoryNameWildcardNameQuery).should(multiMatchQuery);


       //设置高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false); // 如果要多个字段高亮,这项要为false
        highlightBuilder.preTags(""); // 高亮设置
        highlightBuilder.postTags("");
        highlightBuilder.field("name");
        highlightBuilder.field("description");
        highlightBuilder.field("category_name");

        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withIndices("template_graph_contact", "tradition_ml_template_group")
                .withQuery(
                        QueryBuilders.boolQuery()
                                .must(keywordMatchQuery)
                )
                .withHighlightBuilder(highlightBuilder)
                .withPageable(pageable)
                .build();

        //查询后自己构造返回结果,手动分页
        Map search = elasticsearchTemplate.query(nativeSearchQuery, response -> {
                    SearchHits hits = response.getHits();
                    Map map = new HashMap();
                    //手动分页
                    double totalPage = Math.ceil(hits.totalHits / (double)pageSize);
                    map.put("totalElements", hits.totalHits);
                    map.put("totalPages", Double.valueOf(totalPage).intValue());
                    map.put("pageNumber", pageNum);
                    map.put("pageSize", pageSize);
                    List<Map> list = new ArrayList<>();
                    for (SearchHit hit : hits) {
                        if (hits.getHits().length <= 0) {
                            return null;
                        }
                        Map<String, Object> source = hit.getSourceAsMap();

                        //将高亮部分进行替换
                        HighlightField name = hit.getHighlightFields().get("name");
                        HighlightField description = hit.getHighlightFields().get("description");
                        HighlightField categoryName = hit.getHighlightFields().get("category_name");
                        if (name != null) {
                            source.replace("name", name.fragments()[0].toString());
                        }
                        if (description != null) {
                            source.replace("description", description.fragments()[0].toString());
                        }
                        if (categoryName != null) {
                            source.replace("category_name", categoryName.fragments()[0].toString());
                        }
                        list.add(source);
                    }
                    map.put("source", list);
                    return map;
                });

你可能感兴趣的:(java后端,es,elasticsearch,大数据,搜索引擎)