本文将演示如何使用ES提供的Java高级包来查询数据,首先API其实就是在底层构建一条DSL查询语句,所以我们首先看一下这条语句:
GET test*/_search
{
"timeout": "60s",
"query": {
"bool": {
"must": [
{
"terms": {
"status.keyword": [
"301",
"302"
],
"boost": 1
}
},
{
"match_phrase": {
"args": {
"query": "786754748671257",
"slop": 0,
"zero_terms_query": "NONE",
"boost": 1
}
}
},
{
"range": {
"@timestamp": {
"from": "2020-05-20T16:00:00.000Z",
"to": "2020-05-21T16:00:00.000Z",
"include_lower": true,
"include_upper": false,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"track_total_hits": 2147483647
}
接下来代码里的绑定查询条件部分都是围绕这条语句来写的
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>4.5.6version>
dependency>
<dependency>
<groupId>org.elasticsearchgroupId>
<artifactId>elasticsearchartifactId>
<version>7.0.1version>
dependency>
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-high-level-clientartifactId>
<version>7.0.1version>
dependency>
<dependency>
<groupId>joda-timegroupId>
<artifactId>joda-timeartifactId>
<version>2.10.1version>
dependency>
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.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.*;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.joda.time.DateTime;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class ESReadTest {
// ES的用户名,密码,地址
private final String user = "user";
private final String password = "password";
private final String hostname = "127.0.0.1";
private String indexName;
private RestHighLevelClient client;
// 用来将北京时间转换成UTC时间
public String getUTCStr(String date) {
String returnDate = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
returnDate = new DateTime(sdf.parse(date)).plusHours(-8).toString("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
}
catch (ParseException e)
{
e.printStackTrace();
}
return returnDate;
}
// 初始化Client
public void iniES(String indexName){
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(user, password));
RestClientBuilder builder = RestClient.builder(
new HttpHost(hostname, 9200))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);}});
this.client = new RestHighLevelClient(builder);
this.indexName=indexName;
}
//构建请求
public SearchResponse dslBulider() throws IOException {
SearchRequest searchRequest = new SearchRequest(this.indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// hit 返回值(bool 查询返回条数)
// searchSourceBuilder.size(0);
// searchSourceBuilder.from(0);
// 准确计数
searchSourceBuilder.trackTotalHits(true);
// 超时时间60s
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
// 绑定查询条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// status字段为301或302
boolQueryBuilder.must(QueryBuilders.termsQuery("status.keyword", new String[]{"301","302"}));
// args字段包含786754748671257
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("args","786754748671257"));
// 时间大于等于2020-05-21 00:00:00,小于2020-05-22 00:00:00
boolQueryBuilder.must(QueryBuilders.rangeQuery("@timestamp").gte(getUTCStr("2020-05-21 00:00:00")).lt(getUTCStr("2020-05-22 00:00:00")));
// 绑定bool query
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
// 打印dsl语句
System.out.println("dsl is:"+searchRequest.source());
// 发起请求并接收响应
SearchResponse searchResponse = this.client.search(searchRequest, RequestOptions.DEFAULT);
return searchResponse;
}
// 解析响应
public List<String> dslParse(SearchResponse searchResponse) {
List<String> jsonStringList=new ArrayList<>();
for (SearchHit hit : searchResponse.getHits().getHits()) {
jsonStringList.add(hit.getSourceAsString());
}
return jsonStringList;
}
// 关闭Client
public void closeES(){
try {
this.client.close();
}catch (Exception e){
e.printStackTrace();
}
}
// 运行
public void run(){
try {
// 初始化并传入index名
this.iniES("test*");
// 获取查询结果并打印
List<String> jsonStringList = this.dslParse(this.dslBulider());
for (String json : jsonStringList) {
System.out.println(json);
}
}catch (Exception e){
e.printStackTrace();
}finally {
this.closeES();
}
}
public static void main(String[] args) {
ESReadTest esReadTest=new ESReadTest();
esReadTest.run();
}
}
程序运行后将以json格式打印出符合查询条件的数据
以上介绍了按条件简单查询的例子,下一篇里将会介绍如何绑定聚合条件进行聚合查询