使用elasticsearch的java-api进行查询

1.前言

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

2.数据

3.  InitClient

用来初始化客户端mysql

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("192.168.1.101", 9200, "http"),
//                        new HttpHost("192.168.1.102", 9200, "http"),
                        new HttpHost("192.168.1.103", 9200, "http")
                        )
        );
        return client;
    };
}

用来初始化带有密码的客户端sql

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;

public class InitClient {
    public static RestHighLevelClient getClient(){
		/** 用户认证对象 */
		final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
		/** 设置帐号密码 */
		credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "123456"));
		/** 建立rest client对象 */
		RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200))
				.setHttpClientConfigCallback(new HttpClientConfigCallback() {
					@Override
					public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
						return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
					}
				});
		RestHighLevelClient client = new RestHighLevelClient(builder);
		return client;
    	
    };
}

4.查询

4.1查询全部

无条件状况下,查询全部apache

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

结果:api

4.2match

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

因为我这里没有设置中文分词,实际上效果并非很好ide

例1:ui

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

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

但结果是这样的:rest

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

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

结果:

相关文章
相关标签/搜索