doSuggest.java
package es; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; 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.unit.TimeValue; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.DisMaxQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import com.alibaba.fastjson.JSONObject; public class doSuggest { /** * 做自动补全 * @param index 索引 * @param type1 类型1 * @param type2 类型2 * @param size 大小 * @param queryStr 查询语句 * @param cityCode 城市代码 * @return */ public String doSuggest(String index, String type1, String type2, Integer size, String key,Integer cityCode) { if(StringUtils.isBlank(key)){ return null; } key = key.toLowerCase(); List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); ClientHelper clientHelper = new ClientHelper(); Client client = clientHelper.getClient(); //先查询区域,区域优先 SearchRequestBuilder searchRequestBuilder1 = client.prepareSearch(index).setTypes(type1).setSearchType(SearchType.DFS_QUERY_THEN_FETCH); if (size == null || size <= 0) size = 10; DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery(); TermQueryBuilder name = QueryBuilders.termQuery("districtName", key); TermQueryBuilder fpy = QueryBuilders.termQuery("fpy", key); TermQueryBuilder spy =QueryBuilders.termQuery("spy", key); disMaxQueryBuilder.add(name); disMaxQueryBuilder.add(fpy); disMaxQueryBuilder.add(spy); SortBuilder sortBuilder = SortBuilders.fieldSort("num").order(SortOrder.DESC) ; SortBuilder spySort = SortBuilders.fieldSort("districtCode").order(SortOrder.ASC); QueryBuilder fileter = null; if(cityCode != null){ fileter = QueryBuilders.termQuery("cityCode", cityCode); } SearchResponse response = searchRequestBuilder1.setQuery(disMaxQueryBuilder).setPostFilter(fileter).addSort(sortBuilder).addSort(spySort).setSize(size) .setTimeout(TimeValue.timeValueMinutes(2)).execute().actionGet(); SearchHits hits = response.getHits(); if (hits.getTotalHits() > 0) { for (SearchHit hit : hits) { Map<String, Object> source = hit.getSource(); source.put("id", hit.getId()); source.put("index", hit.getIndex()); source.put("resultType","district"); result.add(source); } size = size - Long.valueOf(hits.getTotalHits()).intValue(); if(size>0){ //开始搜索区域和名称里面都带有该字符的信息 DisMaxQueryBuilder qyDisMaxQueryBuilder = QueryBuilders.disMaxQuery(); TermQueryBuilder qyname = QueryBuilders.termQuery("districtName", key); TermQueryBuilder qyfpy = QueryBuilders.termQuery("districtNameFPY", key); TermQueryBuilder qyspy =QueryBuilders.termQuery("districtNameSPY", key); qyDisMaxQueryBuilder.add(qyname); qyDisMaxQueryBuilder.add(qyfpy); qyDisMaxQueryBuilder.add(qyspy); DisMaxQueryBuilder nameDisMaxQueryBuilder = QueryBuilders.disMaxQuery(); TermQueryBuilder stageNamesTerm = QueryBuilders.termQuery("stageNames", key); TermQueryBuilder stagefpy = QueryBuilders.termQuery("fpy", key); TermQueryBuilder stagespy = QueryBuilders.termQuery("spy", key); nameDisMaxQueryBuilder.add(stageNamesTerm); nameDisMaxQueryBuilder.add(stagefpy); nameDisMaxQueryBuilder.add(stagespy); Client client2 = clientHelper.getClient(); BoolQueryBuilder query = QueryBuilders.boolQuery().must(qyDisMaxQueryBuilder).must(nameDisMaxQueryBuilder); SortBuilder sortBuilder2 = SortBuilders.fieldSort("sortNum").order(SortOrder.DESC) ; QueryBuilder fileter2 = null; if(cityCode != null){ fileter2 = QueryBuilders.termQuery("cityCode", cityCode); } //先查询区域,区域优先 SearchRequestBuilder searchRequestBuilder2 = client2.prepareSearch(index).setTypes(type2).setSearchType(SearchType.DFS_QUERY_THEN_FETCH); SearchResponse response2 =searchRequestBuilder2.setQuery(query).setPostFilter(fileter2).addSort(sortBuilder2).setSize(size) .setTimeout(TimeValue.timeValueMinutes(2)).execute().actionGet() ; SearchHits hits2 = response2.getHits(); if(hits2.getTotalHits()>0){ for(SearchHit hit : hits2){ Map<String, Object> source = hit.getSource(); source.put("id", hit.getId()); source.put("index", hit.getIndex()); source.put("hitDistrict","true"); source.put("resultType","stage"); result.add(source); } size = size - Long.valueOf(hits2.getTotalHits()).intValue(); } } if(size>0){ SearchHits hits3 = searchData(client, index, type2, 10, key,cityCode); if(hits3.getTotalHits()>0){ for (SearchHit hit : hits3) { if(size<=0){ break; } String id = hit.getId(); boolean exists =false; if(result!=null&&result.size()>0){ for(Map<String, Object> ex : result){ String exId = (String)ex.get("id"); if(id.equals(exId)){ exists = true; break; } } } if(!exists){ Map<String, Object> source = hit.getSource(); source.put("id", hit.getId()); source.put("index", hit.getIndex()); source.put("hitDistrict","false"); source.put("resultType","stage"); result.add(source); size--; } } } } }else{ SearchHits hits2 = searchData(client, index, type2, size, key,cityCode); if(hits2.getTotalHits()>0){ for (SearchHit hit : hits2) { Map<String, Object> source = hit.getSource(); source.put("id", hit.getId()); source.put("index", hit.getIndex()); source.put("hitDistrict","false"); source.put("resultType","stage"); result.add(source); } } } return JSONObject.toJSONString(result); } private SearchHits searchData(Client client,String index,String type,Integer size,String key,Integer cityCode){ //再检索楼盘类型中的数据 SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type).setSearchType(SearchType.DFS_QUERY_THEN_FETCH); DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery(); TermQueryBuilder stageNamesTerm =QueryBuilders.termQuery("stageNames", key); TermQueryBuilder fpyTerm =QueryBuilders.termQuery("fpy", key); TermQueryBuilder spyTerm =QueryBuilders.termQuery("spy", key); disMaxQueryBuilder.add(stageNamesTerm); disMaxQueryBuilder.add(fpyTerm); disMaxQueryBuilder.add(spyTerm); SortBuilder sortBuilder = SortBuilders.fieldSort("sortNum").order(SortOrder.DESC) ; QueryBuilder fileter = null; if(cityCode != null){ fileter = QueryBuilders.termQuery("cityCode", cityCode); } SearchResponse response = searchRequestBuilder.setQuery(disMaxQueryBuilder).setPostFilter(fileter).addSort(sortBuilder).setSize(size) .setTimeout(TimeValue.timeValueMinutes(2)).execute().actionGet(); SearchHits hits = response.getHits(); return hits; } }
test.java
/** * 测试自动补全 */ @Test public static void doSuggest(){ doSuggest doSuggest = new doSuggest(); String index = "newhouse"; String type1 = "area"; String type2 = "stagename"; Integer pageSize = 10; String key = "h"; String doSuggest2 = doSuggest.doSuggest(index, type1, type2, pageSize, key, 1); System.out.println(doSuggest2); }
ClientHelper.java
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); } }