首页 > 其他分享 >es查询

es查询

时间:2022-12-16 15:02:32浏览次数:28  
标签:search sb String org 查询 new import es

es全表查询

需求:

根据关键字匹配某张表所有字段数据,进行并进行高亮显示。使用模糊查询

解决思路:

  1. 查询索引所有字段
  2. 拼接查询条件
  3. 解析查询条件

遇到的问题:

  1. 电话号码也要求高亮,但是因为电话号码是不分词的,所以这里我们使用 keyword类型和wildcardQuery配合使用。keyword类型是不支持高亮的,所以我们写了一个手动高亮的方法
  2. 想要做到mysql的like的作用使用matchPhrcaseQuery的短语匹配

代码:

1.查询索引的所有字段(获取索引结构)

 private  String[] getMappingStructure(RestHighLevelClient client, String Mapping) {
        //获取索引结构
        GetMappingsRequest request = new GetMappingsRequest();
        request.indices(Mapping);
        GetMappingsResponse mapping = null;
        try {
            mapping = client.indices().getMapping(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        AtomicReference<String> sb = new AtomicReference<>("");
        mapping.mappings().forEach((k,v)->{
            v.getSourceAsMap().forEach((k2,v2)->{
                sb.set(v2.toString());
            });
        });
        String sb2 = sb.toString().substring(1,sb.toString().length()-1);
        String[] split = sb2.split("}, ");
        List<String> strings = Arrays.asList(split);
        ArrayList<String> arr = new ArrayList<>();
        strings.forEach(s->{
            if (s.indexOf("text") != -1){
                String ss = s.split("=")[0];
                if (!"id".equals(ss)){
                    if (!"zc_area".equals(ss)){
                        arr.add(ss);
                    }
                }
            }
        });
        String[] sple2 = arr.toArray(new String[arr.size()]);
        return sple2;
    }

2.拼接查询条件

        //构建分页条件
        Integer startIndex = ( current - 1 ) * size;
        //获取索引结构
        String[] sple2 = getMappingStructure(client, Mapping);
		// 1.准备Request
        SearchRequest request2 = new SearchRequest(Mapping);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().trackTotalHits(true);;
        //布尔查询
        BoolQueryBuilder builder = new BoolQueryBuilder();
        String uscc = "";
        String legal_rep_tel = "";
        // 2.准备DSL
        for (String s : sple2) {
            if ("uscc".equals(s) || "legal_rep_tel".equals(s)){
                builder.should(QueryBuilders.wildcardQuery(s+".keyword","*"+search+"*"));
            }else{
                builder.should(QueryBuilders.matchPhraseQuery(s,search));
            }
        }
        searchSourceBuilder.query(builder);
        //拼接分页
        searchSourceBuilder.from(startIndex).size(size);
        // 2.2、指定高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        for (String s : sple2) {
            highlightBuilder.field(s)
                    .preTags(start)
                    .postTags(end);
            searchSourceBuilder.highlighter(highlightBuilder);
        }
        request2.source().sort("dwmc.keyword", SortOrder.ASC);
        request2.source(searchSourceBuilder);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request2, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

3.解析响应数据

public String getRed(String str,String search){
        if (str.contains(search)){
            int i = str.indexOf(search);
            String substring = str.substring(0, i);
            String substring1 = str.substring(i, i + search.length());
            String substring2 = str.substring(i + search.length(), str.length());
            substring2 = getRed(substring2,search);
            StringBuilder sb = new StringBuilder();
            sb.append(substring);
            sb.append(start);
            sb.append(substring1);
            sb.append(end);
            sb.append(substring2);
            return sb.toString();
        }
        return "";
    }
    //解析响应数据
    private  Page<AdsQiyeBasicInfoES> getAdsQiyeBasicInfoESPage(Integer current, Integer size, String[] sple2, SearchResponse response,String search) {
        SearchHits hits = response.getHits();
        //总记录数
        long value = hits.getTotalHits().value;
        List<AdsQiyeBasicInfoES> list = new ArrayList<>();
        for (SearchHit hit : hits.getHits()) {
            //响应数据转对象
            AdsQiyeBasicInfoES adsQiyeBasicInfoES = JSONUtil.toBean(hit.getSourceAsString().toString(), AdsQiyeBasicInfoES.class);
            //解析高亮部分数据,使用反射赋值
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                for (String s : sple2) {
                    // 根据字段名获取高亮结果
                    HighlightField highlightField = highlightFields.get(s);
                    if (highlightField != null) {
                        // 获取高亮值
                        String v = highlightField.getFragments()[0].string();
                        try {
                            Field declaredField = adsQiyeBasicInfoES.getClass().getDeclaredField(s);
                            declaredField.setAccessible(true);
                            declaredField.set(adsQiyeBasicInfoES,v);
                        } catch (NoSuchFieldException e) {
                            throw new RuntimeException(e);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
            //不能分词数据进行手动高亮
            String uscc = adsQiyeBasicInfoES.getUscc();
            String legalRepTel = adsQiyeBasicInfoES.getLegal_rep_tel();
            if (uscc != null && legalRepTel != null){
                if (uscc.contains(search)){
                    uscc = getRed(uscc,search);
                }
                if (legalRepTel.contains(search)){
                    legalRepTel = getRed(legalRepTel,search);
                }
                adsQiyeBasicInfoES.setUscc(uscc);
                adsQiyeBasicInfoES.setLegal_rep_tel(legalRepTel);
            }
            list.add(adsQiyeBasicInfoES);
        }
        //封装响应数据
        Page<AdsQiyeBasicInfoES> page = new Page<>(current, size, value);
        page.setRecords(list);
        return page;

    }

完整代码


import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.springem.citybrain.controller.vo.AdsQiyeBasicInfoEsVo;
import com.springem.citybrain.dao.entity.AdsQiyeBasicInfoES;
import com.springem.citybrain.service.ElasticsearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.GetMappingsResponse;
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.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {

    private static final String indexName = "*********";
    private static final String start = "<font color='red'>";
    private static final String end = "</font>";

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public Page<AdsQiyeBasicInfoES> seach(AdsQiyeBasicInfoEsVo vo) {
        return getAdsQiyeBasicInfoBySearch(restHighLevelClient,indexName,vo.getSearch(),vo.getCurrent(),vo.getSize());
    }

    public Page<AdsQiyeBasicInfoES> getAdsQiyeBasicInfoBySearch(RestHighLevelClient client, String Mapping, String search, Integer current, Integer size) {
        //构建分页条件
        Integer startIndex = ( current - 1 ) * size;
        //获取索引结构
        String[] sple2 = getMappingStructure(client, Mapping);
        // 1.准备Request
        SearchRequest request2 = new SearchRequest(Mapping);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().trackTotalHits(true);;
        //布尔查询
        BoolQueryBuilder builder = new BoolQueryBuilder();
        String uscc = "";
        String legal_rep_tel = "";
        // 2.准备DSL
        for (String s : sple2) {
            if ("uscc".equals(s) || "legal_rep_tel".equals(s)){
                builder.should(QueryBuilders.wildcardQuery(s+".keyword","*"+search+"*"));
            }else{
                builder.should(QueryBuilders.matchPhraseQuery(s,search));
            }
        }
        searchSourceBuilder.query(builder);

        //拼接分页
        searchSourceBuilder.from(startIndex).size(size);

        // 2.2、指定高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        for (String s : sple2) {
            highlightBuilder.field(s)
                    .preTags(start)
                    .postTags(end);
            searchSourceBuilder.highlighter(highlightBuilder);
        }
        request2.source().sort("dwmc.keyword", SortOrder.ASC);
        request2.source(searchSourceBuilder);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request2, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //解析响应数据
        Page<AdsQiyeBasicInfoES> page = getAdsQiyeBasicInfoESPage(current, size, sple2, response,search);
        return page;
    }

    public String getRed(String str,String search){
        if (str.contains(search)){
            int i = str.indexOf(search);
            String substring = str.substring(0, i);
            String substring1 = str.substring(i, i + search.length());
            String substring2 = str.substring(i + search.length(), str.length());
            substring2 = getRed(substring2,search);
            StringBuilder sb = new StringBuilder();
            sb.append(substring);
            sb.append(start);
            sb.append(substring1);
            sb.append(end);
            sb.append(substring2);
            return sb.toString();
        }
        return "";
    }
    //解析响应数据
    private  Page<AdsQiyeBasicInfoES> getAdsQiyeBasicInfoESPage(Integer current, Integer size, String[] sple2, SearchResponse response,String search) {
        SearchHits hits = response.getHits();
        //总记录数
        long value = hits.getTotalHits().value;
        List<AdsQiyeBasicInfoES> list = new ArrayList<>();
        for (SearchHit hit : hits.getHits()) {
            //响应数据转对象
            AdsQiyeBasicInfoES adsQiyeBasicInfoES = JSONUtil.toBean(hit.getSourceAsString().toString(), AdsQiyeBasicInfoES.class);
            //解析高亮部分数据,使用反射赋值
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                for (String s : sple2) {
                    // 根据字段名获取高亮结果
                    HighlightField highlightField = highlightFields.get(s);
                    if (highlightField != null) {
                        // 获取高亮值
                        String v = highlightField.getFragments()[0].string();
                        try {
                            Field declaredField = adsQiyeBasicInfoES.getClass().getDeclaredField(s);
                            declaredField.setAccessible(true);
                            declaredField.set(adsQiyeBasicInfoES,v);
                        } catch (NoSuchFieldException e) {
                            throw new RuntimeException(e);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
            //不能分词数据进行手动高亮
            String uscc = adsQiyeBasicInfoES.getUscc();
            String legalRepTel = adsQiyeBasicInfoES.getLegal_rep_tel();
            if (uscc != null && legalRepTel != null){
                if (uscc.contains(search)){
                    uscc = getRed(uscc,search);
                }
                if (legalRepTel.contains(search)){
                    legalRepTel = getRed(legalRepTel,search);
                }
                adsQiyeBasicInfoES.setUscc(uscc);
                adsQiyeBasicInfoES.setLegal_rep_tel(legalRepTel);
            }
            list.add(adsQiyeBasicInfoES);
        }
        //封装响应数据
        Page<AdsQiyeBasicInfoES> page = new Page<>(current, size, value);
        page.setRecords(list);
        return page;
    }

    //获取索引结构
    private  String[] getMappingStructure(RestHighLevelClient client, String Mapping) {
        //获取索引结构
        GetMappingsRequest request = new GetMappingsRequest();
        request.indices(Mapping);
        GetMappingsResponse mapping = null;
        try {
            mapping = client.indices().getMapping(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        AtomicReference<String> sb = new AtomicReference<>("");
        mapping.mappings().forEach((k,v)->{
            v.getSourceAsMap().forEach((k2,v2)->{
                sb.set(v2.toString());
            });
        });
        String sb2 = sb.toString().substring(1,sb.toString().length()-1);
        String[] split = sb2.split("}, ");
        List<String> strings = Arrays.asList(split);
        ArrayList<String> arr = new ArrayList<>();
        strings.forEach(s->{
            if (s.indexOf("text") != -1){
                String ss = s.split("=")[0];
                //筛选出不要的字段
                if (!"id".equals(ss)){
                    if (!"zc_area".equals(ss)){
                        arr.add(ss);
                    }
                }
            }
        });
        String[] sple2 = arr.toArray(new String[arr.size()]);
        return sple2;
    }
}

标签:search,sb,String,org,查询,new,import,es
From: https://www.cnblogs.com/fengziHHH/p/16987355.html

相关文章