Elasticsearch--java API(queryMultiField多条件查询)亲测
queryMultiField.java
package es; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.elasticsearch.action.search.ClearScrollRequestBuilder; import org.elasticsearch.action.search.ClearScrollResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.AndQueryBuilder; import org.elasticsearch.index.query.OrQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.RangeQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.highlight.HighlightField; import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import com.alibaba.fastjson.JSON; public class queryMultiField { /** * 查询多个字段 * @param index 索引 * @param type 类型 * @param pageNo 页码 * @param size 页面大小 * @param must 必查的字段及值 * @param should 非必查的字段及值 * @param rangeLists 查询范围 * @param sortMaps 排序 * @param fields 高亮字段 * @return */ public String queryMultiField(String index, String type, Integer pageNo, Integer size, Map<String, Object> must, Map<String, Object> should, List<Map<String, Object>> rangeLists, Map<String, Object> sortMaps, List<String> fields) { ClientHelper clientHelper = new ClientHelper(); 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<Map<String, Object>> lists = new ArrayList<Map<String, Object>>(); try { OrQueryBuilder or = null; AndQueryBuilder and = null; // 构建or查询 if (should != null && !should.isEmpty()) { Iterator<String> 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<String> 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 (Map<String, Object> map : 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("<span style=\"color:red\">") .setHighlighterPostTags("</span>"); } // 查询(该查询已返回第一分片的数据) SearchResponse response = searchRequestBuilder.setSize(size).setScroll(TimeValue.timeValueMinutes(1)) .execute().actionGet(); // 取总计数 long count = response.getHits().getTotalHits(); //scrollId用来清除 List<String> scrollIds = new ArrayList<String>(); for (Integer i = 1; i <= pageNo; i++) { scrollIds.add(response.getScrollId()); if (i.equals(pageNo)) { // 取值 SearchHits hits = response.getHits(); for (SearchHit hit : hits) { Map<String, HighlightField> 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 + "")); return JSON.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 + "")); return JSON.toJSONString(result); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 清除scroll,缓解ES内存占用 * @param client * @param scrollIdList * @return */ private boolean clearScroll(Client client,List<String> scrollIdList){ ClearScrollRequestBuilder clearScrollRequestBuilder = client.prepareClearScroll(); clearScrollRequestBuilder.setScrollIds(scrollIdList); ClearScrollResponse response = clearScrollRequestBuilder.get(); return response.isSucceeded(); } }
test.java
/** * 测试queryMultiField */ @Test public static void queryMultiField(){ queryMultiField querymultifield = new queryMultiField(); String index = "es_test5"; String type = "book"; Integer pageNo = 1; Integer pageSize = 10; Map<String, Object> mustmap = new HashMap<String, Object>(); mustmap.put("title", "技术"); Map<String, Object> shouldMap = new HashMap<String, Object>(); // shouldMap.put("name", "java"); List<Map<String, Object>> rangeLists = new ArrayList<Map<String, Object>>(); Map<String, Object> price = new HashMap<String, Object>(); price.put("from", 80); price.put("to", 90); price.put("field", "price"); rangeLists.add(price); Map<String, Object> sortMaps = new LinkedHashMap<String, Object>(); sortMaps.put("price", "desc"); String msg = querymultifield.queryMultiField(index, type, pageNo, pageSize, mustmap, shouldMap, rangeLists, sortMaps, null); System.out.println(msg); }
ClientHelper
package es; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.plugin.deletebyquery.DeleteByQueryPlugin; import org.elasticsearch.shield.ShieldPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.web.bind.annotation.InitBinder; /** * Es服务器初始化类 * @author Administrator * */ public class ClientHelper { //log4j private static Logger logger = LoggerFactory.getLogger(ClientHelper.class); //存放es集群名称以及嗅探设置 private Settings setting; //es客户端存放集合 private Map<String, Client> clientMap = new ConcurrentHashMap<String, Client>(); //ip端口号集合 private Map<String, Integer> ips = new HashMap<String, Integer>(); //默认集群名称 private String clusterName = "elasticsearch"; public ClientHelper(){ init(); } private static class ClientHolder{ private static final ClientHelper INSTANCE = new ClientHelper(); } public static final ClientHelper getInstance(){ return ClientHolder.INSTANCE; } /** * 得到客户端连接 * @return */ public Client getClient() { return getClient(clusterName); } /** * 得到客户端连接 * @return */ public Client getClient(String clusterName) { Client c = clientMap.get(clusterName); return c; } /** * 初始化EsClient */ public void init(){ Resource resource = new ClassPathResource("config/config.properties"); try { Properties properties = PropertiesLoaderUtils.loadProperties(resource); String host = properties.getProperty("host"); String port = properties.getProperty("port"); clusterName = properties.getProperty("clusterName"); String [] hosts = host.split(";"); String [] ports = port.split(";"); for(int i=0;i< hosts.length;i++){ int portNo = Integer.valueOf(ports[i].trim()); ips.put(hosts[i].trim(), portNo); } } catch (Exception e) { logger.error(e.getMessage()); e.printStackTrace(); } setting = Settings.settingsBuilder() .put("client.transport.sniff",true) .put("cluster.name",clusterName) .build(); addClient(setting, getAllAddress(ips)); } /** * 查询所有ES服务器地址 * * @return */ public List<InetSocketTransportAddress> getAllAddress(Map<String, Integer>ips){ List<InetSocketTransportAddress> addressList = new ArrayList<InetSocketTransportAddress>(); for(String ip:ips.keySet()){ try { addressList.add(new InetSocketTransportAddress(InetAddress.getByName(ip),ips.get(ip))); } catch (UnknownHostException e) { logger.error(e.getMessage()); e.printStackTrace(); } } return addressList; } /** * 往集群中增加ES服务器 * @param setting 设置 * @param transportAddress 传输地址 */ public void addClient(Settings setting, List<InetSocketTransportAddress> transportAddress) { Client client = new TransportClient.Builder().addPlugin(ShieldPlugin.class).addPlugin(DeleteByQueryPlugin.class).settings(setting).build() .addTransportAddresses(transportAddress .toArray(new InetSocketTransportAddress[transportAddress.size()])); clientMap.put(setting.get("cluster.name"), client); } }
划船不用桨、杨帆不等风、一生全靠浪