ES高级查询,高亮显示

package xxx.xxx.xxx.xxx;

import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;

/**
 * ElasticSearch高级查询基本操作
 *
 *  操作的入口TransportClient
 */
public class ElasticSearchQuery {
    private TransportClient tc;
    private int port = 9300;
    private String clusterName = "bigdata";
    private String node_1 = "hadoop01";
    private String node_2 = "hadoop02";
    private String node_3 = "hadoop03";
    private String[] indices = {"bigdata","bank"};
    @Before
    public void setUp() throws UnknownHostException {
        Settings setting = Settings.builder()
                .put("cluster.name",clusterName)
                .put("analyzer","ik")
                .build();
        tc = TransportClient.builder().settings(setting).build();
        TransportAddress hadoop = new InetSocketTransportAddress(InetAddress.getByName(node_1),port);
        TransportAddress spark = new InetSocketTransportAddress(InetAddress.getByName(node_2),port);
        TransportAddress storm = new InetSocketTransportAddress(InetAddress.getByName(node_3),port);
        tc.addTransportAddresses(hadoop,spark,storm);
    }

    /**
     * 查找包涵Apache的数据信息
     */
    @Test
    public void testSearch(){
//        tc.prepareSearch(indices)
//                .setSearchType(SearchType.DEFAULT)
//                .setQuery(QueryBuilders.matchQuery("author", "Apache"))
//                .get();
        SearchResponse response = tc.prepareSearch(indices)//设置要进行查询的方式,有4中查询方式:QUERY_AND_FETCH、QUERY_THEN_FETCH、DFS_QUERY_AND_FETCH、DFS_QUERY_THEN_FETCH
                .setSearchType(SearchType.DEFAULT)//设置查询的内容,和在哪些字段中进行查询,要通过QueryBuilders来进行设置
                .setQuery(QueryBuilders.matchQuery("author", "Apache"))
                .get();
        SearchHits hits = response.getHits();
        long totalHits = hits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        for(SearchHit searchHit:hits){
            printSearchHit(searchHit);
        }
    }

    @Test
    public void testSearch_02(){
        SearchResponse searchResponse = tc.prepareSearch(indices)
                .setSearchType(SearchType.DEFAULT)
                .setQuery(QueryBuilders.prefixQuery("name", "h"))
                .addSort("name", SortOrder.DESC)
                .setFrom(0)
                .setSize(10)
                .get();
        SearchHits hits = searchResponse.getHits();
        long totalHits = hits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        for(SearchHit searchHit: hits){
            printSearchHit(searchHit);
        }
    }

    /**
     * 查询年龄在35到40之间的成员信息
     */
    @Test
    public void testSearch_03(){
        SearchResponse searchResponse = tc.prepareSearch(indices)
                .setSearchType(SearchType.DEFAULT)
                .setQuery(QueryBuilders.rangeQuery("age").gte(35).lte(40))
                .addSort("balance", SortOrder.DESC)
                .setFrom(0)
                .setSize(2)
                .get();
        SearchHits hits = searchResponse.getHits();
        long totalHits = hits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        for(SearchHit searchHit:hits){
            printSearchHit(searchHit);
        }
    }

    /**
     * 执行聚合操作
     * 查询年龄在35到40之间的平均年龄
     */
    @Test
    public void testSearch_04(){
        SearchResponse searchResponse = tc.prepareSearch(indices)
                .setSearchType(SearchType.DEFAULT)
                .setQuery(QueryBuilders.rangeQuery("age").gte(35).lte(40))
                .addAggregation(AggregationBuilders.avg("avg_age").field("age"))
                .get();
        SearchHits hits = searchResponse.getHits();
        long totalHits = hits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        Aggregations aggregations = searchResponse.getAggregations();
        Map aggregationMap = aggregations.asMap();
        for(Map.Entry map:aggregationMap.entrySet()){
            String key = map.getKey();
            //由Aggregations---->强转为InternalAvg,才拿到平均值
            InternalAvg aggregation = (InternalAvg)map.getValue();
            System.out.println("key = " + key);
            System.out.println("aggregation = " + aggregation.getValue());
        }
    }

    /**
     * 代码的高亮显示
     * HighLight
     * keyword
     * 对于这种高亮显示,就是在查询关键字之前和之后分别追加前缀和后缀
     * 前缀:pre
     * 后缀:post
     *
     * 设置高亮注意的地方:
     *  1、设置高亮字段:addHighlightedField
     *  2、设置高亮的前缀和后缀:
     *      setHighlighterPreTags("")
     *      setHighlighterPostTags("")
     *  3、获取高亮数据
     *      searchHit.getHighlightFields()中的fragment获取
     */
    @Test
    public void testSearch_05(){
        SearchResponse response = tc.prepareSearch(indices)
                .setSearchType(SearchType.DEFAULT)
                .setQuery(QueryBuilders.matchQuery("name", "hadoop02"))
                .addHighlightedField("name")
                .setHighlighterPreTags("")
                .setHighlighterPostTags("")
                .get();
        SearchHits searchHits = response.getHits();
        long totalHits = searchHits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        for(SearchHit searchHit : searchHits){
            System.out.println(" ================== " );
            Map highlightFields = searchHit.getHighlightFields();
            for(Map.Entry me : highlightFields.entrySet()){
                String key = me.getKey();
                System.out.println("key = " + key);
                HighlightField highlightField = me.getValue();
                String name = highlightField.getName();
                System.out.println("name = " + name);
                Text[] fragments = highlightField.getFragments();
                String hightStr = "";
                for(Text text : fragments){
                    hightStr += text.toString();
                }
                System.out.println("hightStr = " + hightStr);
            }
        }
    }


    /**
     * 查询中文
     *
     * 分词:
     *  我们发现设置Query为termQuery,QueryBuilders.termQuery("author", "孙")有结果
     *  而Query为termQuery,QueryBuilders.termQuery("author", "孙鹏")没有结果
     *  这是因为中文分词的原因,英文分词非常简单:就是通过一个个的空格进行拆分,而汉字的拆分默认情况下就是一个字一个字的拆
     *
     *  我们要想查询孙鹏 或者鹏飞这些词组的时候,默认的拆分方式就提供不了数据了,为了满足用户的需要,在软件发展过程中就有非常多的
     *  各种各样的分词法(庖丁解牛分词法,IK分词法)
     *
     *  如果使用了IK等分词法,对索引库中已经存在的数据不执行相应的分词,只有对新增的数据才会执行相应的分词!!!
     */
    @Test
    public void testSearch_Chinese(){
        indices = new String[]{"bigdata"};
        SearchResponse response = tc.prepareSearch(indices)
                .setSearchType(SearchType.DEFAULT)      //奥利猫(ik之前)    法拉狗
                .setQuery(QueryBuilders.termQuery("author", "奥利"))
                .get();
        SearchHits hits = response.getHits();
        long totalHits = hits.getTotalHits();
        System.out.println("老王为您找到相关结果约 " + totalHits);
        for(SearchHit searchHit : hits){
            printSearchHit(searchHit);
        }
    }

    private void printSearchHit(SearchHit searchHit){
        String index = searchHit.getIndex();
        String type = searchHit.getType();
        String id = searchHit.getId();
        long version = searchHit.getVersion();
        float score = searchHit.getScore();
        Map source = searchHit.getSource();
        System.out.println("index "+index);
        System.out.println("type "+type);
        System.out.println("id "+id);
        System.out.println("version "+version);
        System.out.println("score "+score);
        System.out.println("source "+source);
    }

    @After
    public void cleanUp(){
        if(tc != null){
            tc.close();
        }
    }
}

你可能感兴趣的:(elasticsearch)