Elasticsearch 7.6.x: Error: failed to cast StringTerms for elasticSearch 7.6.x: Error: failed to cast StringTerms for ElasticSearch And so on (and then comes back to fix the problem)

Aggregate query statement

Match_phrase --> GET /skuinfo/_search {match_phrase --> GET /skuinfo/_search {"query": {
    "match_phrase": {
      "name": "Huawei"}},"aggs": {
    "categoryName": {
      "terms": {
        "field": "categoryName.keyword"}}}} # match: match --> GET /skuinfo/_search {"query": {
    "match": {
      "name": "Huawei"}},"aggs": {
    "categoryName": {
      "terms": {
        "field": "categoryName.keyword"}}}}Copy the code

Integrated use of SpringBoot

/ * * *@Auther: csp1999
 * @Date: 2021/01/18/16:04
 * @Description: Search for the SkuService interface implementation class */
@Service
public class SkuEsServiceImpl implements SkuEsService {

    @Autowired
    private SkuEsMapper skuEsMapper;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

// @Autowired
// @Qualifier("restHighLevelClient")
// private RestHighLevelClient client;

    /** * search by criteria: multiple criteria search **@param searchParamMap
     * @return* /
    @Override
    public Map<String, Object> search(Map<String, String> searchParamMap) {

        // Build search criteria: search criteria constructor
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        if(searchParamMap ! =null && searchParamMap.size() > 0) {
            // Search by keyword
            String keywords = searchParamMap.get("keywords");

            if (StringUtils.isEmpty(keywords)) {
                keywords = "Huawei";// Assign a default value for keywords
            }

            -->SELECT category_name FROM 'tb_sku' WHERE 'name' LIKE '% Huawei %' GROUP BY category_name
            // Get the class name data set:
            // category_name
            / / switches
            / / cell phone
            searchQueryBuilder.addAggregation(
                    // AggregationBuilders aggregate conditional builders
                    // terms("categoryName") : alias the column
                    / / field (" categoryName. Keyword ") :
                    // categoryName field name
                    //. Keyword facilitates aggregate search: When querying term, the type of the keyword in es must be keyword instead of text, because it is an exact match
                    Exception [type=search_phase_execution_exception, reason=all shards failed] Elasticsearch [type=search_phase_execution_exception, reason=all shards failed]
                    // size Specifies the number of query results. The default value is 10
                    AggregationBuilders
                            .terms("categoryName")
                            .field("categoryName.keyword")
                            .size(50));// If the keyword is not empty, search the keyword data
            if(! StringUtils.isEmpty(keywords)) { searchQueryBuilder.withQuery( QueryBuilders.matchPhraseQuery("name", keywords)
                        // Cannot use: QueryBuilders. MatchQuery ("name", keywords), which results in:
                        // Search huawei --> Huawei can split query, matchPhraseQuery can not split query
                );
            }

            // Paging: defaults to 50 data on page 1
            searchQueryBuilder.withPageable(PageRequest.of(0.50));
        }

        // Search condition constructor construction: NativeSearchQuery
        NativeSearchQuery searchQuery = searchQueryBuilder.build();

        // Perform a search to get the SearchHits collection that encapsulates the results of the response data
        SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(searchQuery, SkuInfo.class);

        / * * get aggregated by categoryName packet classification name after collection * searchHits in the getAggregations () to obtain the Aggregations set * get (" skuCategoryGroup ") Get categoryName Aggregation data for the specified categoryName domain eg:[cell phone, home appliance, cell phone accessories] * Aggregation --> StringTerms
        Before ES7 you can use StringTerms, but after ES7 you are advised to use Terms instead of StringTerms if there is a type conversion error
        Terms terms = searchHits.getAggregations().get("categoryName");
        // Get the set of category names
        List<String> categoryList = this.getStringsCategoryList(terms);


        // Paged the SearchHits collection
        SearchPage<SkuInfo> searchPageFor = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());

        // Total number of records
        long totalElements = searchPageFor.getTotalElements();
        / / the total number of pages
        int totalPages = searchPageFor.getTotalPages();
        // The current number of pages
        int currentPage = searchPageFor.getPageable().getPageNumber();
        // Total records on the current page
        int currentPageRows = searchPageFor.getPageable().getPageSize();

        // Get the required SkuInfo collection data content
        List<SearchHit<SkuInfo>> content = searchPageFor.getContent();

        // Parse and encapsulate the data
        // Encapsulate a Map to store all data and return it
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("totalPage", totalPages);/ / the total number of pages
        resultMap.put("total", totalElements);// Total number of records
        resultMap.put("currentPage", currentPage);/ / the current page
        resultMap.put("currentPageRows", currentPageRows);// Total records on the current page
        resultMap.put("categoryList", categoryList);// Product category name data set
        resultMap.put("rows", content);// Commodity SkuInfo data set

        return resultMap;
    }

    /** * Get categoryList **/ from StringTerms
    private List<String> getStringsCategoryList(Terms terms) {
        List<String> categoryList = new ArrayList<>();

        if(terms ! =null) {
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String keyAsString = bucket.getKeyAsString();// Group value (category name)categoryList.add(keyAsString); }}returncategoryList; }}Copy the code

Add the complete code for aggregating, highlighting, and filtering searches

/ * * *@Auther: csp1999
 * @Date: 2021/01/18/16:04
 * @Description: Search for the SkuService interface implementation class */
@Service
public class SkuEsServiceImpl implements SkuEsService {

    @Autowired
    private SkuEsMapper skuEsMapper;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /** * Import all Sku data from database into ES */
    @Override
    public void importDataToElasticSearch(int start, int end) {
        List
      
        Result<List<Sku>> skuListResult = skuFeign.findAll(start, end);

        // Change List
      
        to List
       
      
        // json.tojsonString (skulistresult.getData ()): Convert the List
      
        in skuListResult toJSON format
      
        // json.parsearray (): Converts a List
      
        in JSON format into a List
       
         collection
       
      
        List<SkuInfo> skuInfoList = JSON.parseArray(JSON.toJSONString(skuListResult.getData()), SkuInfo.class);

        // Iterate over the current skuInfoList
        for (SkuInfo skuInfo : skuInfoList) {

            // Get spec(String Map data) -> convert it to Map ->{' color ': 'Van Gogh Starry Collection ',' version ': '8GB+128GB'}
            Map<String, Object> specMap = JSON.parseObject(skuInfo.getSpec(), Map.class);
            // Assign the specMap attribute in skuInfo
            // The current Map
      
        value Object will be used as the corresponding field (key) value of the Sku Object
      ,object>
            skuInfo.setSpecMap(specMap);
        }

        // Call Mapper to implement data batch import
        skuEsMapper.saveAll(skuInfoList);
    }

    /** * search by criteria: multiple criteria search * // *@param searchParamMap
     * @return* /
    @Deprecated The search(Map
      
        searchParamMap) method is used instead
      ,>
    public Map<String, Object> search2(Map<String, String> searchParamMap) {

        // 1. Build search criteria: search criteria constructor
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
// if (searchParamMap ! = null && searchParamMap.size() > 0) {
        // Search by keyword
        String keywords = searchParamMap.get("keywords");

        if (StringUtils.isEmpty(keywords)) {
            keywords = "Mobile phone";// Assign a default value for keywords
        }

        // If the keyword is not empty, search the keyword data
        if(! StringUtils.isEmpty(keywords)) { searchQueryBuilder.withQuery( QueryBuilders.matchPhraseQuery("name", keywords)
                    // Multiple fields match the search term
// QueryBuilders.multiMatchQuery(keywords, "name.keyword", "categoryName.keyword", "brandNam.keyword")
                    // Cannot use: QueryBuilders. MatchQuery ("name", keywords), which results in:
                    // Search huawei --> Huawei can split query, matchPhraseQuery can not split query
            );
        }

        // Group result sets by category name: [mobile phones, switches]
        -->SELECT category_name FROM 'tb_sku' WHERE 'name' LIKE '% Huawei %' GROUP BY category_name
        // Get the class name data set:
        // category_name
        / / switches
        / / cell phone
        searchQueryBuilder.addAggregation(
                // AggregationBuilders aggregate conditional builders
                // terms("categoryName") : alias the column
                / / field (" categoryName. Keyword ") :
                // categoryName field name
                //. Keyword facilitates aggregate search: When querying term, the type of the keyword in es must be keyword instead of text, because it is an exact match
                Exception [type=search_phase_execution_exception, reason=all shards failed] Elasticsearch [type=search_phase_execution_exception, reason=all shards failed]
                // size Specifies the number of query results. The default value is 10
                AggregationBuilders
                        .terms("categoryName")
                        .field("categoryName.keyword")
                        .size(100));// Group result sets by brand name: [Huawei, Xiaomi, Center, Apple]
        searchQueryBuilder.addAggregation(
                // AggregationBuilders aggregate conditional builders
                // terms("brandName") : alias the column
                / / field (" brandName. Keyword ") :
                // brandName Specifies the field name
                //. Keyword facilitates aggregate search: When querying term, the type of the keyword in es must be keyword instead of text, because it is an exact match
                Exception [type=search_phase_execution_exception, reason=all shards failed] Elasticsearch [type=search_phase_execution_exception, reason=all shards failed]
                // size Specifies the number of query results. The default value is 10
                AggregationBuilders
                        .terms("brandName")
                        .field("brandName.keyword")
                        .size(100));// Group result sets by brand name: [Huawei, Xiaomi, Center, Apple]
        searchQueryBuilder.addAggregation(
                // AggregationBuilders aggregate conditional builders
                // terms("brandName") : alias the column
                / / field (" brandName. Keyword ") :
                // brandName Specifies the field name
                //. Keyword facilitates aggregate search: When querying term, the type of the keyword in es must be keyword instead of text, because it is an exact match
                Exception [type=search_phase_execution_exception, reason=all shards failed] Elasticsearch [type=search_phase_execution_exception, reason=all shards failed]
                // size Specifies the number of query results. The default value is 10
                AggregationBuilders
                        .terms("spec")
                        .field("spec.keyword")
                        .size(100));// Paging: defaults to page 1 with 100 entries
        searchQueryBuilder.withPageable(PageRequest.of(0.100));
/ /}

        / / = = = = = = = = = = = = = = = = = = = = = = = = start filtering query = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if(searchParamMap ! =null) {
            for (String key : searchParamMap.keySet()) {//{brand:"",category:"",spec_ network :" telecom 4G"}
                if (key.startsWith("spec_")) {
                    // Intercept the specification name
                    boolQueryBuilder.filter(QueryBuilders.termQuery("specMap." + key.substring(5) + ".keyword", searchParamMap.get(key)));
                }
            }
        }

        String category = searchParamMap.get("category");
        if(! StringUtils.isEmpty(category)) { boolQueryBuilder.filter(QueryBuilders.termQuery("categoryName", category));
        }

        String brand = searchParamMap.get("brand");
        if(! StringUtils.isEmpty(brand)) { boolQueryBuilder.filter(QueryBuilders.termQuery("brandName", brand));
        }

        // Filter the query
        searchQueryBuilder.withFilter(boolQueryBuilder);
        / / = = = = = = = = = = = = = = = = = = = = = = = = end of filter query = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

        // Search condition constructor construction: NativeSearchQuery
        NativeSearchQuery searchQuery = searchQueryBuilder.build();

        // Perform a search to get the SearchHits collection that encapsulates the results of the response data
        SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(searchQuery, SkuInfo.class);
        / * * get aggregated by categoryName packet classification name after collection * searchHits in the getAggregations () to obtain the Aggregations set * get (" skuCategoryGroup ") Get categoryName Aggregation data for the specified categoryName domain eg:[cell phone, home appliance, cell phone accessories] * Aggregation --> StringTerms
        // Get the set of category names from Terms
        // Note: When the user selects (clicks) a category, the category will be used as the search criteria. In this case, there is no need to perform group search for the category, because the group search data is used to display the category search criteria and does not need to be displayed repeatedly
        Before ES7 you can use StringTerms, but after ES7 you are advised to use Terms instead of StringTerms if there is a type conversion error
        // searchParamMap -> brand
        Terms categoryTerms = searchHits.getAggregations().get("categoryName");
        List<String> categoryList = this.getResultListByTerms(categoryTerms);

        // Get the collection of brand names from Terms
        // Note: When the user selects (clicks) a brand, the brand is selected as the search criteria. In this case, there is no need to conduct group search for the brand, because the data of group search is used to display the brand search criteria, so there is no need to repeat display
        // searchParamMap -> brand
        Terms BrandTerms = searchHits.getAggregations().get("brandName");
        List<String> brandList = this.getResultListByTerms(BrandTerms);

        Terms SpecTerms = searchHits.getAggregations().get("spec");
        // Get the spec domain set
        Map<String, Set<String>> specMap = this.getResultMapByTerms(SpecTerms);

        // Paged the SearchHits collection
        SearchPage<SkuInfo> searchPageFor = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());

        // Total number of records
        long totalElements = searchPageFor.getTotalElements();
        / / the total number of pages
        int totalPages = searchPageFor.getTotalPages();
        // The current number of pages
        int currentPage = searchPageFor.getPageable().getPageNumber();
        // Total records on the current page
        int currentPageRows = searchPageFor.getPageable().getPageSize();

        // Get the required SkuInfo collection data content
        List<SearchHit<SkuInfo>> content = searchPageFor.getContent();

        // Parse and encapsulate the data
        // Encapsulate a Map to store all data and return it
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("totalPage", totalPages);/ / the total number of pages
        resultMap.put("total", totalElements);// Total number of records
        resultMap.put("currentPage", currentPage + 1);/ / the current page
        resultMap.put("currentPageRows", currentPageRows);// Total records on the current page
        resultMap.put("categoryList", categoryList);// Product category name data set
        resultMap.put("brandList", brandList);// Product category name data set
        resultMap.put("specMap", specMap);// Product category name data set
        resultMap.put("rows", content);// Commodity SkuInfo data set

        return resultMap;
    }

    / * * *@param terms
     * @return* /
    @Deprecated // This method is no longer used, only for comparison with the optimized method
    private Map<String, Set<String>> getResultMapByTerms(Terms terms) {

        // key: specifies the specification name
        // value: set of multiple values of the option corresponding to the specification name
        Map<String, Set<String>> specMap = new HashMap<String, Set<String>>();
        Set<String> specValues = new HashSet<String>();

        // 1. Get the spec set of goods encapsulated in terms
        if(terms ! =null) {
            for (Terms.Bucket bucket : terms.getBuckets()) {
                // 2. Teters.getbuckets () to get the spec data line by line (JSON string)
                / / spec: {" screen size ":" 5.5 ""," network ":" telecom 4 g ", "color" : "white", "test" : "s11", "the fuselage memory" : "128 g," "storage" : "16 g", "pixel" : "3 million pixels"}
                String keyAsString = bucket.getKeyAsString();

                // 3. Each loop converts json String spec data to Map
      
        key: specification name value: single value of the option corresponding to the specification name
      ,>
                Map<String, String> map = JSON.parseObject(keyAsString, Map.class);
                // 4. Iterate through the previous step to convert spec to Map
      ,>
                for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
                    //
                    String key = stringStringEntry.getKey();// Specification name eg: phone screen size
                    String value = stringStringEntry.getValue();// The name of the specification corresponds to a single option value eg:5.5 inches

                    SpecMap (HashSet
      
        value); specMap (HashSet
       
         value);
       
      
                    specValues = specMap.get(key);
                    // If specValues do not exist, create a new one
                    if (specValues == null) {
                        specValues = new HashSet<>();
                    }
                    // Store the single parameter in the HashSet(HashSet can be repeated!)
                    specValues.add(value);
                    // 5. Put specValues back into specMapspecMap.put(key, specValues); }}}return specMap;
    }

    /** * retrieves the result set of encapsulated data from Terms */
    @Deprecated // This method is no longer used, only for comparison with the optimized method
    private List<String> getResultListByTerms(Terms terms) {
        List<String> resultList = new ArrayList<>();

        if(terms ! =null) {
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String keyAsString = bucket.getKeyAsString();// Group value (category name/brand name)resultList.add(keyAsString); }}return resultList;
    }

    /** * keyword search (optimized search method) **@param searchMap
     * @return* /
    @Override
    public Map<String, Object> search(Map<String, String> searchMap) {
        // 1. Encapsulate the search criteria (there are several search criteria in the later stage, which encapsulate a method)
        NativeSearchQueryBuilder builder = builderBasicQuery(searchMap);
        // 2. Search by keyword to obtain commodity information under the keyword
        Map<String, Object> resultMap = searchForPage(builder);
        // 3. List of goods by category
// List
      
        categoryList = searchCategoryList(builder);
      
// resultMap.put("categoryList", categoryList);
        // 4. Query the brand category list
// List
      
        brandList = searchBrandList(builder);
      
// resultMap.put("brandList", brandList);
        // Get the total number of entries
        String totalElements = resultMap.get("TotalElements").toString();
        int totalSize = Integer.parseInt(totalElements);
        if (totalSize <= 0) {
            // Check whether totalSize is less than or equal to 0. If it is less than or equal to 0, an out-of-bounds exception will be reported
            totalSize = 10000;
        }
        // 5. Statistical specifications category list
// Map
      
       > specList = searchSpecList(builder,totalSize);
      ,>
// resultMap.put("specList", specList);
        // 6. Encapsulate the retrieved results into a map
        Map<String, Object> map = searchGroupList(builder, totalSize);
        resultMap.putAll(map);
        return resultMap;
    }
    
    /** ** statistical specification classification list query, brand classification list query, commodity classification group statistics implementation (encapsulate a method to return all search criteria return results) **@param builder
     * @return* /
    private Map<String, Object> searchGroupList(NativeSearchQueryBuilder builder, int totalSize) {
        // Aggregate query (category) alias corresponds to fields in Kibana
        builder.addAggregation(AggregationBuilders.terms("skuCategpryName").field("categoryName.keyword").size(totalSize));
        // Aggregate query (brand) alias corresponds to fields in Kibana
        builder.addAggregation(AggregationBuilders.terms("skuBrandName").field("brandName.keyword").size(totalSize));
        // Aggregate query (brand) alias corresponds to fields in Kibana
        builder.addAggregation(AggregationBuilders.terms("skuSpec").field("spec.keyword").size(totalSize));
        // Group the result set
        SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(builder.build(), SkuInfo.class);
        // Paged the SearchHits collection
        SearchPage<SkuInfo> page = SearchHitSupport.searchPageFor(searchHits, builder.build().getPageable());

        // Process the result set
        Aggregations aggregations = page.getSearchHits().getAggregations();
        // Statistical classification
        List<String> categoryList = getGroupList(aggregations, "skuCategpryName");
        // Count brands
        List<String> brandList = getGroupList(aggregations, "skuBrandName");
        // Statistical specifications
        List<String> spceList = getGroupList(aggregations, "skuSpec");
        // Return the List result set of statistical specifications as a Map
        Map<String, Set<String>> specmap = pullMap(spceList);
        // Encapsulate all data into a Map
        Map<String, Object> map = new HashMap<>();
        map.put("categoryList", categoryList);
        map.put("brandList", brandList);
        map.put("specMap", specmap);
        // Returns the final result set
        return map;
    }

    /** * Process aggregate query (category, brand, brand) result set **@param
     * @return* /
    private List<String> getGroupList(Aggregations aggregations, String groupName) {
        Terms terms = aggregations.get(groupName);
        List<String> resultList = new ArrayList<>();

        if(terms ! =null) {
            for (Terms.Bucket bucket : terms.getBuckets()) {
                String keyAsString = bucket.getKeyAsString();// Group value (category name/brand name)resultList.add(keyAsString); }}return resultList;
    }

    /** * Process specification data encapsulation Map **@param list
     * @return* /
    private Map<String, Set<String>> pullMap(List<String> list) {
        Map<String, Set<String>> map = new HashMap<>();
        for (String spec : list) {
            // Convert character JSON data to Map
            Map<String, String> specMap = JSON.parseObject(spec, Map.class);
            / / traverse map
            Set<Map.Entry<String, String>> entrySet = specMap.entrySet();
            for (Map.Entry<String, String> entry : entrySet) {
                // TV sound effect ":
                String key = entry.getKey();
                // Small cinema...
                String value = entry.getValue();
                // Value is multiple and cannot be reused
                // First check if there is a set in the map
                Set<String> set = map.get(key);
                if (set == null) {
                    // Determine if set is empty, if so new HashSet
                    set = new HashSet<>();
                }
                // If set is not empty, add data directly to itset.add(value); map.put(key, set); }}return map;
    }

    /** * Retrieve by keyword **@param builder
     * @return* /
    private Map<String, Object> searchForPage(NativeSearchQueryBuilder builder) {
        // Keyword highlighting
        // Continue to encapsulate the search criteria
        HighlightBuilder.Field field = new HighlightBuilder.Field("name");  //sku name is highlighted if there is a keyword
        field.preTags("<font color='red'>");    // Start tag
        field.postTags("</font>");              // End tag
        field.fragmentSize(100);                // The number of characters to display
        builder.withHighlightFields(field);

        NativeSearchQuery build = builder.build();
        //AggregatedPage<SkuInfo> page = elasticsearchTemplate.queryForPage(build, SkuInfo.class);
        // Group the result set
        SearchHits<SkuInfo> searchHits = elasticsearchRestTemplate.search(builder.build(), SkuInfo.class);
        // Paged the SearchHits collection
        SearchPage<SkuInfo> page = SearchHitSupport.searchPageFor(searchHits, builder.build().getPageable());

        // Fetch the highlighted result data in the object
        // Traversal: process the returned content (highlighted fields replace the original fields)
        for(SearchHit<SkuInfo> searchHit:searchHits){
            // Get the highlighted content in searchHit
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            // Fill the content with highlighted content
            searchHit.getContent().setName(highlightFields.get("name") = =null ? searchHit.getContent().getName():highlightFields.get("name").get(0));
        }

        Map<String, Object> map = new HashMap<>();
        // Product result set
        map.put("rows", page.getContent());
        / / the total number of article
        map.put("TotalElements", page.getTotalElements());
        / / the total number of pages
        map.put("TotalPages", page.getTotalPages());
        // paging the current page number
        map.put("pageNum", build.getPageable().getPageNumber() + 1);
        // Display the number of entries per page
        map.put("pageSize", build.getPageable().getPageSize());

        return map;
    }

    /** * This method is used to encapsulate the search criteria NativeSearchQueryBuilder **@param searchMap
     * @return* /
    private NativeSearchQueryBuilder builderBasicQuery(Map<String, String> searchMap) {
        // Encapsulate the search criteria
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        // Add filter criteria
        BoolQueryBuilder boolBuilder = new BoolQueryBuilder();
        if(searchMap ! =null) {

            // 1. Search by keyword
            String keywords = searchMap.get("keywords");
            if(! StringUtils.isEmpty(keywords)) { builder.withQuery(QueryBuilders.matchPhraseQuery("name", keywords));
            }

            // continue the concatenation condition
            // 2. Filter by product category
            String category = searchMap.get("category");
            if(! StringUtils.isEmpty(category)) { boolBuilder.must(QueryBuilders.matchPhraseQuery("categoryName", category));
            }

            // 3. Filter by product brand
            String brand = searchMap.get("brand");
            if(! StringUtils.isEmpty(brand)) { boolBuilder.must(QueryBuilders.matchPhraseQuery("brandName", brand));
            }

            // 4. Filter according to product specifications (select several specifications)
            // ::spec_ Screen size: 5.7, spec_ memory: 40GB
            Set<String> keys = searchMap.keySet();
            for (String key : keys) {
                // Determine if the specification starts with spec_
                if (key.startsWith("spec_")) {
                    String value = searchMap.get(key).replace("\ \"."");
                    boolBuilder.must(QueryBuilders.matchQuery("specMap." + key.substring(5) + ".keyword", value)); }}// 5. Filter by commodity price (segment)
            String price = searchMap.get("price");
            if(! StringUtils.isEmpty(price)) {(min ~ Max / >price / 
                String[] priceArray = price.split("-");
                // If the price parameter passed is one, it is greater than (>=) the query
                boolBuilder.must(QueryBuilders.rangeQuery("price").gte(priceArray[0]));
                if (priceArray.length > 1) {
                    // If the price parameter is two, it is less than (<=) query
                    boolBuilder.must(QueryBuilders.rangeQuery("price").lte(priceArray[1])); }}// select * from ASC DESC;
            // Sort the fields
            String sortField = searchMap.get("sortField");
            // Sort rules (ASC DESC)
            String sortRule = searchMap.get("sortRule");
            if (!StringUtils.isEmpty(sortField)) {
                builder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.valueOf(sortRule)));
            }
        }
        // 7. Add the filter criteria to the Builder
        builder.withFilter(boolBuilder);

        Age1: current page (page) age2: display data per page (size)
        String page = searchMap.get("pageNum");
        if (StringUtils.isEmpty(page)) {
            // The default start page is the first page
            page = "1";
        }
        int pageNum = Integer.parseInt(page);
        // Dynamically get front-end pass
        String size = searchMap.get("size");
        // The default page displays 20 items of data
        if (StringUtils.isEmpty(size)) {
            size = "20";
        }
        int pageSize = Integer.parseInt(size);
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
        builder.withPageable(pageable);
        returnbuilder; }}Copy the code