【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
1.前言
elsaticsearch版本是6.8.3,使用的java-api是基于Java High Level REST Client.
2.数据
3. InitClient
用来初始化客户端
package com.htkj.elasticsearch;
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("htkj101", 9200, "http"),
// new HttpHost("htkj102", 9200, "http"),
new HttpHost("htkj224", 9200, "http")
)
);
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();
}
}
结果:
注意:本文归作者所有,未经作者允许,不得转载