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);
        
    }
}

 

posted @ 2018-08-10 15:02  十月围城小童鞋  阅读(4123)  评论(0编辑  收藏  举报