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