ELasticsearch实现多字段查询和多字段高亮

本文深入探讨了在Elasticsearch中如何构建复杂的查询条件,包括基本查询、多字段高亮及结果处理。通过示例代码,详细解析了如何使用BoolQueryBuilder进行must、should和mustNot操作,以及如何实现多字段的高亮显示,最后展示了如何处理高亮后的查询结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基本的查询方法

// 构建基本查询条件
	private QueryBuilder buildBasicQueryWithFilter(SearchRequest request) {
		String flag = "";
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
		BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
		//如果输入的查询条件为空,则查询所有数据
		if(request.getKey() == null || "".equals(request.getKey())) {
        	queryBuilder.must(QueryBuilders.matchAllQuery());
        	return queryBuilder;
        }
        // 基本查询条件
        //queryBuilder.must(QueryBuilders.matchQuery(request.getKeyField(), request.getKey()));
		//queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields()));//多字段查询,字段直接是or的关系
        //过滤条件
        Map<String, Object> filter = request.getFilter();
        if(filter != null) {
        	for (Map.Entry<String, Object> entry : filter.entrySet()) {
                String key = entry.getKey();
                flag = key;
                Map<String, String> value = (Map<String, String>) entry.getValue();
                	for (Map.Entry<String, String> map : value.entrySet()) {
                		String filterKey = map.getKey();
                		String filterValue = map.getValue();
                		if(key == "and") {
                			queryBuilder.filter(QueryBuilders.termQuery(filterKey, filterValue));
                		}
                		if(key == "or") {
                			shouldQuery.should(QueryBuilders.termQuery(filterKey, filterValue));
                		}
                		if(key == "not") {
                			queryBuilder.mustNot(QueryBuilders.termQuery(filterKey, filterValue));
                		}
                	}
            }
        }
        if(flag == "or") {
        	queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields())).must(shouldQuery);//解决should和must共用不生效问题
        }else {
        	queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields()));//多字段查询,字段直接是or的关系
        }
        
		return queryBuilder;
	}
	

2.构建多字段高亮

QueryBuilder basicQuery =buildBasicQueryWithFilter(request);
        //1.1多字段高亮
        HighlightBuilder.Field highlightFields = null;
        List<HighlightBuilder.Field> lst = new ArrayList<>();
        for(String field : request.getKeyFields()) {
        	highlightFields = new HighlightBuilder.Field(field);
        	highlightFields.preTags("<span style=\"color:red\">").postTags("</span>");
        	lst.add(highlightFields);
        }
        HighlightBuilder.Field[] ary = new HighlightBuilder.Field[lst.size()];
        for(int i=0;i<lst.size();i++) {
        	ary[i] = lst.get(i);
        }
        queryBuilder.withQuery(basicQuery).withHighlightFields(ary);
//5.2 高亮查询结果
        AggregatedPage<Item> pageInfo = template.queryForPage(queryBuilder.build(), Item.class
        		,new SearchResultMapper() {

					@Override
					public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
							Pageable pageable) {
						List<Map<String,Object>> list=new ArrayList<>();
		                SearchHits hits = response.getHits();
		                for (SearchHit searchHit : hits) {
		                    if (hits.getHits().length <= 0) {
		                        return null;
		                    }
		                    Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
		                    //将高亮值放入高亮字段
		                    for(String keyField : request.getKeyFields()){//循环遍历得到分词(高亮)字段名称
		                    	String keyFieldValue= (String) sourceAsMap.get(keyField); //取出分词字段值
		                    	HighlightField highlightFieldValue =searchHit.getHighlightFields().get(keyField);//取出分词字段值,关键词部分高亮
		                    	if(highlightFieldValue == null) {
		                    		sourceAsMap.put(keyField, keyFieldValue);
		                    	}else {
		                    		String hcontent = highlightFieldValue.fragments()[0].toString();//取值
		                    		sourceAsMap.put(keyField, hcontent);
		                    	}
		                    }
		                    list.add(sourceAsMap);
		                }
		                if (list.size() > 0) {
		                    return new AggregatedPageImpl<T>((List<T>) list);
		                }
						return null;
					}
        	
        }
        );

3.补充SearchRequest部分字段

private String key;// 搜索条件
private String[] keyFields; //全文检索的字段名称

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值