使用elasticsearch的java-api进行查询
< 返回列表时间: 2020-01-13来源:OSCHINA
【围观】麒麟芯片遭打压成绝版,华为亿元投入又砸向了哪里?>>>
1.前言
elsaticsearch版本是6.8.3,使用的java-api是基于Java High Level REST Client.
2.数据

3. InitClient
用来初始化客户端 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; }; }
用来初始化带有密码的客户端 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查询所有
无条件情况下,查询所有 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(); } }
结果:
热门排行