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