Elasticsearch查询配置(Elasticsearch+springboot)

这段代码的功能是查询出es里面的数据进行分页展示,使用的jar版本为2.4


大概流程

添加maven依赖

        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>2.4.0</version>
        </dependency>

properties属性文件配置

spring.elasticsearch.host=192.168.101.123
spring.elasticsearch.port=9300

spring的配置文件,初始化TransportClient 对象

package com.unioncast.ssp.front.config;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * ElasticsearchConfig
 *
 * @author zhangzhe
 * @date 2017/2/21 16:33
 */
@Configuration
@PropertySource(value = "classpath:/elasticsearch.properties")
public class ElasticsearchConfig {

    @Value("${spring.elasticsearch.host}")
    private String host;
    @Value("${spring.elasticsearch.port}")
    private int port;

    private static final Logger LOG = LogManager.getLogger(ElasticsearchConfig.class);

    @Bean
    public TransportClient elasticsearchClient(){	//向spring注入es的客户端操作对象
        TransportClient transportClient = null;

        Settings settings = Settings.settingsBuilder()
                .put("cluster.name", "bigData-cluster").build();
        try {
            transportClient = TransportClient
                    .builder()
                    .settings(settings)
                    .build()
                    .addTransportAddress(
                            new InetSocketTransportAddress(InetAddress.getByName(host), port)
                    );
        } catch (UnknownHostException e) {
            LOG.error("创建elasticsearch客户端失败");
        }
        LOG.info("创建elasticsearch客户端成功");

        return transportClient;

    }

}


对数据进行查询操作的实现类

package com.unioncast.ssp.front.service.ssp.elasticsearchData;

import com.unioncast.common.page.Pagination;
import com.unioncast.common.restClient.RestResponse;
import com.unioncast.common.ssp.model.SspAdvertiser;
import com.unioncast.common.ssp.model.SspCreative;
import com.unioncast.ssp.front.service.ssp.SspAdvertiserService;
import com.unioncast.ssp.front.service.ssp.SspCreativeService;
import com.unioncast.ssp.front.service.ssp.SspOrderService;
import com.unioncast.ssp.front.service.ssp.SspPlanService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.UnknownHostException;
import java.util.*;

/**
 * @author zhangzhe
 * @date 2017/2/21 10:25
 */


@Component
public class ElasticsearchADReportImpl implements ElasticsearchADReport {

    private static final Logger LOG = LogManager.getLogger(ElasticsearchADReportImpl.class);

    private static final String INDEX = "hehe";		//es的索引表名称
    private static final String TYPE = "kafka_type";	//es的索引类型
    private static final Integer PAGESIZE = 10;		//分页的每页显示数
    private static final String ESC = "ip";		//用于排序的字段
    @Resource
    TransportClient transportClient;		//注入es操作对象

    @Resource
    SspAdvertiserService sspAdvertiserService;

    @Resource
    SspOrderService sspOrderService;

    @Resource
    SspPlanService sspPlanService;

    @Resource
    SspCreativeService sspCreativeService;

    //es查询
    public Pagination<Map<String, Object>> esADReport(Long accountId, Long advertiserId, Long orderId, Long planId, Long creativeId,
                                                      Integer currentPageNo, String startTime, String endTime)
            throws UnknownHostException {

        List<Map<String, Object>> list = new ArrayList<>();
        Integer totalCount = 0;

        QueryBuilder query = QueryBuilders.boolQuery();

        //用户ID	这里的matchPhraseQuery代表精确查询,同样使用matchQuery也可以,matchPhrasePrefixQuery代表的是模糊查询
        if (accountId != null) {
            query = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchPhraseQuery("accountId", accountId));		

        }

        //广告主ID
        if (advertiserId != null) {
            query = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchPhraseQuery("advertiserId", advertiserId));

        }

        //订单ID
        if (orderId != null) {
            query = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchPhraseQuery("orderId", orderId));

        }

        //计划ID
        if (planId != null) {
            query = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchPhraseQuery("planId", planId));

        }

        //创意ID
        if (creativeId != null) {
            query = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchPhraseQuery("creativeId", creativeId));

        }

        //总数
/*        SearchResponse rsTotal = transportClient.prepareSearch(INDEX).setTypes(TYPE)
                .setSearchType(SearchType.DFS_QUERY_AND_FETCH)
                .setQuery(query)
                .addSort(ESC, SortOrder.DESC)
                .setExplain(true).execute().actionGet();
        if (rsTotal != null && rsTotal.getHits().getHits().length != 0) {
            totalCount = (int) rsTotal.getHits().getTotalHits();
//            System.out.println("totalHits: "+totalHits);
//            totalCount=rsTotal.getHits().getHits().length;
//            System.out.println("totalCount: "+totalCount);
        }*/


        //搜索	这里的.setSearchType属性代表索引的查询方式,几种方式的区别我写在末尾
        int pageIndex = (currentPageNo - 1) * PAGESIZE;
        SearchResponse rs = transportClient.prepareSearch(INDEX).setTypes(TYPE)	
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)		//这里非常重要,当初就是因为类型填写错误,导致查询出超出预计结果的数据
                .setQuery(query)				//查询条件
                .addSort(ESC, SortOrder.DESC)	//排序,DESC为倒序
                .setFrom(pageIndex).setSize(PAGESIZE)		//数据的索引(从0开始)和查询条数
                .setExplain(true).execute().actionGet();


        // 遍历查询结果
        if (rs != null && rs.getHits().getHits().length != 0) {
            totalCount = (int) rs.getHits().getTotalHits();		//这一段可以获取结果的总数,对应的是分页类的总页数
            SearchHit[] hits = rs.getHits().getHits();			//这个就是es查询出的结果,设置的是从索引开始查询10条
            //List<SearchHit> page = page(currentPageNo, PAGESIZE, hits);
            for (SearchHit hit : hits) {
                Map<String, Object> source = hit.getSource();	//这个方法使查出的数据表现为map格式,同样也可以得到string类型的json数据

                //针对id做出的查询
                Map<String, Object> map = new HashMap();	//一下是根据es里面存放的id,向数据库查询name值用于展示

                Long sspAdvertiserId = (Long) source.get("sspAdvertiserId");
                if (sspAdvertiserId != null) {
                    String sspAdvertiserName = findSspAdvertiserName(sspAdvertiserId);
                    map.put("sspAdvertiserName", sspAdvertiserName);
                }

                Long sspOrderId = (Long) source.get("sspOrderId");
                if (sspOrderId != null) {
                    String sspOrderName = findSspOrderName(sspOrderId);
                    map.put("sspOrderName", sspOrderName);
                }

                Long sspPlanId = (Long) source.get("sspPlanId");
                if (sspPlanId != null) {
                    String sspPlanName = findSspPlanName(sspPlanId);
                    map.put("sspPlanName", sspPlanName);
                }

                Long sspCreativeId = (Long) source.get("sspCreativeId");
                if (sspCreativeId != null) {
                    String sspCreativeName = findSspCreativeName(sspCreativeId);
                    map.put("sspCreativeName", sspCreativeName);
                }
                source.putAll(map);

                list.add(source);
                //System.out.println(hit.getSourceAsString());
            }
        }

        return new Pagination<Map<String, Object>>(totalCount, PAGESIZE, currentPageNo, list.toArray(new Map[]{}));	//分页处理类

    }


    private String findSspAdvertiserName(Long advertiserId) {
        SspAdvertiser sspAdvertiser = new SspAdvertiser();
        sspAdvertiser.setId(advertiserId);
        RestResponse restResponse = sspAdvertiserService.find(sspAdvertiser);
        ArrayList result = (ArrayList) restResponse.getResult();
        LinkedHashMap map = (LinkedHashMap) result.get(0);
        String name = (String) map.get("name");
        return name;
    }

    private String findSspOrderName(Long orderId) {
        String name = null;
        try {
            RestResponse restResponse = sspOrderService.find(orderId);
            ArrayList result = (ArrayList) restResponse.getResult();
            LinkedHashMap map = (LinkedHashMap) result.get(0);
            name = (String) map.get("name");
        } catch (Exception e) {
            LOG.error("订单查询失败");
        }
        return name;
    }

    private String findSspPlanName(Long planId) {
        String name = null;
        try {
            RestResponse restResponse = sspPlanService.find(planId);
            LinkedHashMap map = (LinkedHashMap) restResponse.getResult();
            name = (String) map.get("name");
        } catch (Exception e) {
            LOG.error("计划查询失败");
        }
        return name;
    }

    private String findSspCreativeName(Long creativeId) {
        SspCreative creative = new SspCreative();
        creative.setId(creativeId);
        RestResponse restResponse = sspCreativeService.find(creative);
        ArrayList result = (ArrayList) restResponse.getResult();
        LinkedHashMap map = (LinkedHashMap) result.get(0);
        String name = (String) map.get("creativeName");
        return name;
    }


/*    public List<SearchHit> page(int pageNo, int pageSize, SearchHit[] hits) {
        List<SearchHit> result = new ArrayList<>();
        if (hits != null && hits.length > 0) {
            int allCount = hits.length;
            int pageCount = (allCount + pageSize - 1) / pageSize;
            if (pageNo >= pageCount) {
                pageNo = pageCount;
            }
            if (pageNo < 1) {
                pageNo = 1;
            }
            int start = (pageNo - 1) * pageSize;
            int end = pageNo * pageSize;
            if (end >= allCount) {
                end = allCount;
            }
            for (int i = start; i < end; i++) {
                result.add(hits[i]);
            }
        }
        return (result != null && result.size() > 0) ? result : null;
    }*/

}


附:

查询类型

1、query and fetch
向索引的所有分片(shard)都发出查询请求,各分片返回的时候把元素文档(document)和计算后的排名信息一起返回。这种搜索方式是最快的。因为相比下面的几种搜索方式,这种查询方法只需要去shard查询一次。但是各个shard返回的结果的数量之和可能是用户要求的size的n倍。
2、query then fetch(默认的搜索方式)
如果你搜索时,没有指定搜索方式,就是使用的这种搜索方式。这种搜索方式,大概分两个步骤,第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。这种方式返回的document与用户要求的size是相等的。
3、DFS query and fetch
这种方式比第一种方式多了一个初始化散发(initial scatter)步骤,有这一步,据说可以更精确控制搜索打分和排名。
4、DFS query then fetch
比第2种方式多了一个初始化散发(initial scatter)步骤。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值