packagees;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importorg.apache.commons.lang3.StringUtils;importorg.elasticsearch.action.search.ClearScrollRequestBuilder;importorg.elasticsearch.action.search.ClearScrollResponse;importorg.elasticsearch.action.search.SearchRequestBuilder;importorg.elasticsearch.action.search.SearchResponse;importorg.elasticsearch.action.search.SearchType;importorg.elasticsearch.client.Client;importorg.elasticsearch.common.text.Text;importorg.elasticsearch.common.unit.TimeValue;importorg.elasticsearch.index.query.AndQueryBuilder;importorg.elasticsearch.index.query.OrQueryBuilder;importorg.elasticsearch.index.query.QueryBuilder;importorg.elasticsearch.index.query.QueryBuilders;importorg.elasticsearch.index.query.RangeQueryBuilder;importorg.elasticsearch.search.SearchHit;importorg.elasticsearch.search.SearchHits;importorg.elasticsearch.search.highlight.HighlightField;importorg.elasticsearch.search.sort.SortBuilder;importorg.elasticsearch.search.sort.SortBuilders;importorg.elasticsearch.search.sort.SortOrder;importcom.alibaba.fastjson.JSON;public classqueryMultiField {/*** 查询多个字段
*@paramindex 索引
*@paramtype 类型
*@parampageNo 页码
*@paramsize 页面大小
*@parammust 必查的字段及值
*@paramshould 非必查的字段及值
*@paramrangeLists 查询范围
*@paramsortMaps 排序
*@paramfields 高亮字段
*@return
*/
public String queryMultiField(String index, String type, Integer pageNo, Integer size, Mapmust,
Map should, List> rangeLists, MapsortMaps,
Listfields) {
ClientHelper clientHelper= newClientHelper();
Client client=clientHelper.getClient();
SearchRequestBuilder searchRequestBuilder=client.prepareSearch(index).setTypes(type)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);if (pageNo == null || pageNo <= 0)
pageNo= 1;if (size == null || size <= 0)
size= 20;
List> lists = new ArrayList>();try{
OrQueryBuilder or= null;
AndQueryBuilder and= null;//构建or查询
if (should != null && !should.isEmpty()) {
Iterator keys =should.keySet().iterator();while(keys.hasNext()) {
String key=keys.next();if (should.get(key) != null &&StringUtils.isNotBlank(should.get(key).toString())) {
QueryBuilder condition=QueryBuilders.termQuery(key, should.get(key));if (or == null) {
or=QueryBuilders.orQuery(condition);
}else{
or.add(condition);
}
}
}
}//构建AND查询
if (must != null && !must.isEmpty()) {
Iterator keys =must.keySet().iterator();while(keys.hasNext()) {
String key=keys.next();if (null != must.get(key) &&StringUtils.isNotBlank(must.get(key).toString())) {
QueryBuilder condition=QueryBuilders.termQuery(key, must.get(key));if (and == null) {
and=QueryBuilders.andQuery(condition);
}else{
and.add(condition);
}
}
}
}if (or != null) {if (and != null) {
and.add(or);
searchRequestBuilder.setQuery(and);
}else{
searchRequestBuilder.setQuery(or);
}
}else{if (and != null) {
searchRequestBuilder.setQuery(and);
}else{
searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
}
}//构造范围查询参数
RangeQueryBuilder qb = null;if (rangeLists != null && rangeLists.size() > 0) {for (Mapmap : rangeLists) {if (map != null && (!map.isEmpty())) {
qb= QueryBuilders.rangeQuery(StringUtils.trim(map.get("field").toString()));if(map.containsKey("from")){
qb.from(StringUtils.trim(map.get("from").toString()));
}if(map.containsKey("to")){
qb.to(StringUtils.trim(map.get("to").toString()));
}if(!map.containsKey("from")&&!map.containsKey("to")){
qb=null;
}
}
}
searchRequestBuilder.setPostFilter(qb);
}//构造排序参数
SortBuilder sortBuilder = null;if (sortMaps != null && sortMaps.size() > 0) {for(Object key : sortMaps.keySet()) {
sortBuilder=SortBuilders.fieldSort((String) key)
.order(StringUtils.trim(sortMaps.get(key).toString()).equalsIgnoreCase("ASC") ?SortOrder.ASC
: SortOrder.DESC);
searchRequestBuilder.addSort(sortBuilder);
}
}//构造高亮字段
if (fields != null && fields.size() > 0) {for(String field : fields) {
searchRequestBuilder.addHighlightedField(field);
}
searchRequestBuilder.setHighlighterEncoder("UTF-8").setHighlighterPreTags("")
.setHighlighterPostTags("");
}//查询(该查询已返回第一分片的数据)
SearchResponse response = searchRequestBuilder.setSize(size).setScroll(TimeValue.timeValueMinutes(1))
.execute().actionGet();//取总计数
long count =response.getHits().getTotalHits();//scrollId用来清除
List scrollIds = new ArrayList();for (Integer i = 1; i <= pageNo; i++) {
scrollIds.add(response.getScrollId());if(i.equals(pageNo)) {//取值
SearchHits hits =response.getHits();for(SearchHit hit : hits) {
Map result =hit.highlightFields();if (fields != null) {//用高亮字段替换搜索字段
for(String field : fields) {
HighlightField titleField=result.get(field);if (titleField == null) {continue;
}
Text[] titleTexts=titleField.fragments();
StringBuffer value= new StringBuffer("");for(Text text : titleTexts) {
value.append(text);
}
hit.getSource().put(field, value.toString());
}
}
hit.getSource().put("id", hit.getId());
hit.getSource().put("index", hit.getIndex());
hit.getSource().put("type", hit.getType());
lists.add(hit.getSource());
}
Pager result= new Pager(hits.getTotalHits(), lists, Long.parseLong(pageNo + ""));returnJSON.toJSONString(result);
}else{//查询下一分页的数据
response = client.prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueMinutes(8))
.execute().actionGet();
}
}
clearScroll(client, scrollIds);
Pager result= new Pager(count, lists, Long.parseLong(pageNo + ""));returnJSON.toJSONString(result);
}catch(Exception e) {
e.printStackTrace();
}return null;
}/*** 清除scroll,缓解ES内存占用
*@paramclient
*@paramscrollIdList
*@return
*/
private boolean clearScroll(Client client,ListscrollIdList){
ClearScrollRequestBuilder clearScrollRequestBuilder=client.prepareClearScroll();
clearScrollRequestBuilder.setScrollIds(scrollIdList);
ClearScrollResponse response=clearScrollRequestBuilder.get();returnresponse.isSucceeded();
}
}