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

結果:

相關文章
相關標籤/搜索