支付宝红包
京东盲盒抽奖
幸运转盘
秒杀
自营热卖
支付宝红包

使用elasticsearch的java-api进行查询

此城无心忘少年 1年前   阅读数 429 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

1.前言

elsaticsearch版本是6.8.3,使用的java-api是基于Java High Level REST Client.

2.数据

3.  InitClient

用来初始化客户端

package com.htkj.elasticsearch;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;

public class InitClient {
    public static RestHighLevelClient getClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
//                        new HttpHost("htkj101", 9200, "http"),
//                        new HttpHost("htkj102", 9200, "http"),
                        new HttpHost("htkj224", 9200, "http")
                        )
        );
        return client;
    };
}

4.查询

4.1查询所有

无条件情况下,查询所有

    private static void queryAll(){
        try(RestHighLevelClient client = InitClient.getClient()){
            //创建SearchRequest
            SearchRequest searchRequest = new SearchRequest();
            //指定索引为poems
            searchRequest.indices("poems");
            //创建SearchSourceBuilder
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //创建BoolQueryBuilder 用于添加条件
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            //排序 按照索引中的id升序排序
            searchSourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));
            //分页
            searchSourceBuilder.from(0);
            searchSourceBuilder.size(20);
            //将查询条件放入searchSourceBuilder中
            searchSourceBuilder.query(boolQueryBuilder);
            //searchRequest解析searchSourceBuilder
            searchRequest.source(searchSourceBuilder);
            //获取SearchResponse
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            //获取分片结果
            SearchHits hits = searchResponse.getHits();
            SearchHit[] searchHits = hits.getHits();
            //获得数据
            for (SearchHit hit : searchHits) {
                String sourceAsString = hit.getSourceAsString();
                System.out.println(sourceAsString);
            }
            //关闭连接
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:

4.2match

match查询主要是针对分词情况下的匹配查询.默认情况下,是按照空格分词的.

由于我这里没有设置中文分词,实际上效果并不是很好

例1:

            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("content", "三千");
            boolQueryBuilder.must(matchQueryBuilder);

这里想查找content字段下,有"三千"的内容,想要的结果应该是只会返回"日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。"

但结果是这样的:

可以看到返回了三条结果,只有望庐山瀑布满足了有"三"和"千"这两个内容,月下独酌只满足了"三",元日满足了"千"

4.3term

term查询是完全匹配查询,只有完全匹配字段的内容,才会查到,

使用term查询,一定要使用keyword属性,否则会被分词,就查不到了.

例1:查找作者是李白的结果

            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("author.keyword", "李白");
            boolQueryBuilder.must(termQueryBuilder);

结果:

4.4wildcard

wildcard查询是通配符查询,相当于mysql中的like,这个也要使用keyword属性

例1:查找诗歌中包含"三千"的内容,

            WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("content.keyword", "*三千*");
            boolQueryBuilder.must(wildcardQueryBuilder);

结果:

可以看到只返回了一个结果,这也是wildcard和match不同的地方

4.5prefix

prefix查询是前缀查询,也是使用keyword属性

例1:查找所有李姓作者

            PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("author.keyword", "李");
            boolQueryBuilder.must(prefixQueryBuilder);

结果:

4.6嵌套查询

对于多条件查询,有时候需要创建多个QueryBuilders.boolQuery()来进行嵌套

例1:查找content字段下内容中有"月"的或者有"酒"和"雨"

 select * from poems where content like '月' or(content like '酒' and content like'雨')
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            BoolQueryBuilder boolQueryBuilderContent = QueryBuilders.boolQuery();
            WildcardQueryBuilder wildcardQueryBuilderMoon = QueryBuilders.wildcardQuery("content.keyword", "*月*");
            WildcardQueryBuilder wildcardQueryBuilderAlcohol = QueryBuilders.wildcardQuery("content.keyword", "*酒*");
            WildcardQueryBuilder wildcardQueryBuilderRainy = QueryBuilders.wildcardQuery("content.keyword", "*雨*");
            boolQueryBuilderContent.must(wildcardQueryBuilderAlcohol).must(wildcardQueryBuilderRainy);
            boolQueryBuilder.should(wildcardQueryBuilderMoon).should(boolQueryBuilderContent);

结果:

5.聚合统计

例1:计算每个诗人的诗歌数

select author, count(*) as author_count from poems group by author
    private static void aggregation(){
        try(RestHighLevelClient client = InitClient.getClient()){
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("poems");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //指定计数author  这里的author_count可以随意取名 
            TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("author_count").field("author.keyword");
            //将aggregationBuilder 放入searchSourceBuilder
            searchSourceBuilder.aggregation(aggregationBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            //获取count 这里的author_count 要和上面取的名字对应上
            Terms terms = searchResponse.getAggregations().get("author_count");
            //获取结果
            for (Terms.Bucket bucket : terms.getBuckets()) {
                System.out.println("author=" + bucket.getKey()+" count="+bucket.getDocCount());
            }
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:

例2:计算每个朝代每个诗人的诗歌数

select dynasty,author,count(*) as author_count from poems group by dynasty,author
    private static void aggregation(){
        try(RestHighLevelClient client = InitClient.getClient()){
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("poems");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //设置聚合的字段dynasty 和author
            TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("dynasty_count").field("dynasty.keyword");
            TermsAggregationBuilder aggregationBuilder2 = AggregationBuilders.terms("author_count").field("author.keyword");
            //aggregationBuilder2是aggregationBuilder的子聚合
            searchSourceBuilder.aggregation(aggregationBuilder.subAggregation(aggregationBuilder2));
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            //获取dynasty_count
            Terms terms = searchResponse.getAggregations().get("dynasty_count");
            //获取结果
            for (Terms.Bucket bucket : terms.getBuckets()) {
                System.out.println("dynasty=" + bucket.getKey()+" count="+bucket.getDocCount());
                //获取author_count
                Terms terms2 = bucket.getAggregations().get("author_count");
                 for (Terms.Bucket bucket2 : terms2.getBuckets()) {
		                System.out.println("author=" + bucket2.getKey()+ ";  数量=" + bucket2.getDocCount());
		            }
            }
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: