系列文章:
Elasticsearch-05-Elasticsearch-sql组件史上最全详解
Elasticsearch-04-Elasticsearch组件head和kibana详解
Elasticsearch-02-es的restapi使用
Elasticsearch-01-es概念及安装
前言
Elasticsearch 软件是由 Java 语言开发的,所以也可以通过 JavaAPI 的方式对 Elasticsearch
服务进行访问
之前是对ES中的创建/查看/删除索引、创建定义映射、创建/查看/修改/删除文档的这些操作有了一定的了解认识,但是是通过Postman + JSON串的方法来实现的
那么之后仍然是对ES中的索引、映射、文档进行操作,只是方法换成了Java API。
一:导包
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--lombok依赖-->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
二:客户端对象
创建 com.atguigu.es.test.Elasticsearch01_Client 类,代码中创建 Elasticsearch 客户端对象
因为早期版本的客户端对象已经不再推荐使用,且在未来版本中会被删除,所以这里我们采
用高级 REST 客户端对象-RestHighLevelClient
package es;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
/** 创建es客户端
* @author wkl
* @create 2022-06-28 14:56
*/
public class EsClient {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//关闭ES客户端
esClient.close();
}
}
三:客户端操作
1:索引操作
1:创建索引
/** 索引类操作
* @author wkl
* @create 2022-06-28 15:04
*/
public class CreateIndex {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建索引对象
CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
//发送请求
CreateIndexResponse createIndexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("索引操作:"+acknowledged);
//关闭ES客户端
esClient.close();
}
}
2:查看索引
/**
* @author wkl
* @create 2022-06-28 15:15
*/
public class GerIndex {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
GetIndexRequest request = new GetIndexRequest("user");
GetIndexResponse getIndexResponse = esClient.indices().get(request, RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getDataStreams());
System.out.println(getIndexResponse.getSettings());
//关闭ES客户端
esClient.close();
}
}
3:删除索引
/**
* @author wkl
* @create 2022-06-28 15:20
*/
public class DeleteIndex {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("student");
AcknowledgedResponse delete = esClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
//关闭ES客户端
esClient.close();
}
}
4:创建带映射的请求
public void createIndexOfMapping() throws IOException {
//创建请求对象
CreateIndexRequest request = new CreateIndexRequest("user");
//映射规则去别的地方写好,粘过来
String mapping = "{\n" +
" \"properties\": {\n" +
" \"booleanFile\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"date\": {\n" +
" \"type\": \"date\",\n" +
" \"format\": \"yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\"\n" +
" },\n" +
" \"keywordFile\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"longFile\": {\n" +
" \"type\": \"long\"\n" +
" },\n" +
" \"test_keyword_File\": {\n" +
" \"type\": \"text\",\n" +
" \"fields\": {\n" +
" \"keyword\": {\n" +
" \"type\": \"keyword\",\n" +
" \"ignore_above\": 256\n" +
" }\n" +
" }\n" +
" },\n" +
" \"text\": {\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }";
//添加映射规则
request.mapping(mapping, XContentType.JSON);
//发送请求
restHighLevelClient.indices().create(request,RequestOptions.DEFAULT);
}
5:测试索引是否存在
/*
* @description: 测试索引是否存在
* @author: wangkanglu
* @date: 2022/8/28 14:54
* @param:
* @return:
**/
@Test
public void exitIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("user");
boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
2:文档操作
1:创建文档
1:创建实体-我这里使用了lombok代替get,set,这个就不介绍了哈
/**
- @author wkl
- @create 2022-06-28 15:24
*/
@Data
public class User {
private String name;
private String sex;
private int age;
}
2:创建文档
/**
* @author wkl
* @create 2022-06-28 15:25
*/
public class CreateDocument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建文档对象
IndexRequest indexRequest = new IndexRequest("user");
//设置索引及索引中文档的唯一性标识id(如果不指定,则ES会默认随机生成一个id,建议指定id值,也是为了后续查找方便)
indexRequest.id("1");
//创建数据对象
User user = new User();
user.setName("张三");
user.setSex("男");
user.setAge(35);
user.setBir(new Date());
//向es中插入数据,此数据必须是json格式,并且es在后台动态创建映射
indexRequest.source(JSONObject.toJSONString(user), XContentType.JSON);
//发送请求
IndexResponse index = esClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(index.getId());
System.out.println(index.getIndex());
System.out.println(index.getResult());
//关闭ES客户端
esClient.close();
}
}
2:修改文档-局部修改
/**
* @author wkl
* @create 2022-06-28 16:02
*/
public class UpdateDocument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
UpdateRequest updateRequest = new UpdateRequest("user","1");
//updateRequest.index("user").id("1");
//将修改后的内容,以JSON格式写入请求体中
JSONObject jsonObject = new JSONObject();
jsonObject.put("age",26");
//updateRequest.doc(jsonObject);
updateRequest.doc(jsonObject.toJSONString(),XContentType.JSON);
//实时更新
updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
//发送请求 --- 获取响应
UpdateResponse update = esClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(update.getResult());
//关闭ES客户端
esClient.close();
}
}
3:删除文档
/**
* @author wkl
* @create 2022-06-28 16:07
*/
public class DeleteDoucument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建删除文档请求
DeleteRequest deleteRequest = new DeleteRequest();
//设置删除id
deleteRequest.index("user").id("1");
//发送请求
DeleteResponse delete = esClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.getResult());
//关闭ES客户端
esClient.close();
}
}
4:批量新增
public class BatchCreateDocument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建请求对象
BulkRequest bulkRequest = new BulkRequest();
//设置请求参数
bulkRequest.add(new IndexRequest().index("user").id("2").source(JSONObject.toJSONString(new User("李四","男",20,new Date())), XContentType.JSON));
bulkRequest.add(new IndexRequest().index("user").id("3").source(JSONObject.toJSONString(new User("小花","女",18,new Date())), XContentType.JSON));
bulkRequest.add(new IndexRequest().index("user").id("4").source(JSONObject.toJSONString(new User("小雪","女",24,new Date())), XContentType.JSON));
//发送请求
//实时更新
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
BulkResponse bulk = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.getTook());
//关闭ES客户端
esClient.close();
}
}
5:批量删除
/**
* @author wkl
* @create 2022-06-28 16:12
*/
public class BatchDleteDocument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建请求对象
BulkRequest bulkRequest = new BulkRequest();
//设置请求参数
bulkRequest.add(new DeleteRequest().index("user").id("1"));
bulkRequest.add(new DeleteRequest().index("user").id("2"));
//发送请求
//实时更新
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
BulkResponse bulk = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.getItems());
//关闭ES客户端
esClient.close();
}
}
6:批量更新
public class BatchUpdataDocument {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建请求对象
BulkRequest bulkRequest = new BulkRequest();
//设置请求参数
for (int i = 0; i < list.size(); i++) {
JSONObject jsonObject = list.get(i);
String uuid = jsonObject.getString("uuid");
String index = jsonObject.getString("_index");
jsonObject.remove("_index");
bulkRequest.add(new UpdateRequest(index, uuid).doc(jsonObject));
}
//发送请求
//实时更新
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
BulkResponse bulk = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.getTook());
//关闭ES客户端
esClient.close();
}
}
6:根据文档id查询数据(简单)
/*
* @description:根据id查询数据
* @author: wangkanglu
* @date: 2022/8/28 16:25
* @param:
* @return:
**/
@Test
public void getDoc() throws IOException {
//创建查询对象
GetRequest getRequest = new GetRequest("user","1");
GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSONString(documentFields));
}
3:高级查询
1:全量查询-解析结果
/**
* @author wkl
* @create 2022-06-28 16:29
*/
public class Match_allQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建查询的请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询所有数据-查询全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//全量展示命中数量
searchSourceBuilder.trackTotalHits(true);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
//分析结果
SearchHits hits = searchResponse.getHits();
long value = hits.getTotalHits().value;
System.out.println("查询到记录数=" + value);
List<JSONObject> list = new ArrayList<>();
SearchHit[] searchHists = hits.getHits();
if (searchHists.length > 0) {
for (SearchHit hit : searchHists) {
String sourceAsString = hit.getSourceAsString();
JSONObject jsonObject = JSON.parseObject(sourceAsString);
jsonObject.put("_id", hit.getId());
list.add(jsonObject);
}
}
//关闭ES客户端
esClient.close();
}
}
2:条件查询-term 查询,查询条件为关键字,不分词
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class TermQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据-精确的关键词匹配查询, 不对查询条件进行分词。
searchSourceBuilder.query(QueryBuilders.termQuery("age",20));
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
3:分词查询-match
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class MatchQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据-match查询,会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。
searchSourceBuilder.query(QueryBuilders.matchQuery("name","小"));
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
4:分页查询-from&size
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class MatchOfpageQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
// 分页查询
// 当前页其实索引 (第一条数据的顺序号),from
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
5:数据排序-sort
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class SortQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//排序
searchSourceBuilder.sort("age", SortOrder.DESC);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
6:过滤字段-fetch
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class FilterQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//过滤查询
//排除字段
String[] excludes = {};
//包含字段
String[] includes = {"age","sex"};
searchSourceBuilder.fetchSource(includes,excludes);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
7:Bool查询-组合查询-这个常用,可以兼容任何条件
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class BoolQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
//构建bool选择器
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
// 必须包含
boolQueryBuilder.must (QueryBuilders.matchQuery("age", "18"));
// 一定不含
boolQueryBuilder.mustNot (QueryBuilders.matchQuery("name", "zhangsan"));
// 可能包含
boolQueryBuilder.should (QueryBuilders.matchQuery("sex", "女"));
//将bool选择器假如到请求体中
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
8:范围查询-range
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class RangQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("age");
rangeQueryBuilder.gte(18);
rangeQueryBuilder.lte(30);
//将bool选择器加入到请求体中
searchSourceBuilder.query(rangeQueryBuilder);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
//关闭ES客户端
esClient.close();
}
}
9:模糊查询-fuzzi
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class FuzzinQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "小");
searchSourceBuilder.query(fuzzyQueryBuilder.fuzziness(Fuzziness.ONE));
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
SearchHits hits = search.getHits();
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
JSON.toJSONString(search.getAsMap().get("stats_salary"))
//关闭ES客户端
esClient.close();
}
}
10:分组查询
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class AggrGroupQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构建请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询数据-按照年龄分组
//前边的参数是给分组取的名字、后面field是要分组的字段
searchSourceBuilder.aggregation(AggregationBuilders.terms("group_value").field("age"));
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
//构建返回数据
SearchHit[] hits = searchResponse.getHits().getHits();
//构建分组数据
//Aggregation 接口的实现类,Terms 代表最基本的terms聚合
Terms sexValue = searchResponse.getAggregations().get("group_value");
//关闭ES客户端
esClient.close();
}
}
11:聚合查询-分组
/**
* @author wkl
* @create 2022-06-28 17:53
*/
public class AggrQuery {
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构造请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构造组合查询请求体
BoolQueryBuilder query = QueryBuilders.boolQuery();
//过滤数据
query.must(QueryBuilders.termQuery("name","张"));
query.mustNot(QueryBuilders.termQuery("falg","1"));
//聚合分组查询
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("sexvalue").field("sex");
searchSourceBuilder.aggregation(aggregationBuilder);
searchSourceBuilder.query(query);
//分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
searchRequest.source(searchSourceBuilder);
//发送请求
SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);
//构建返回数据
SearchHit[] hits = searchResponse.getHits().getHits();
//构建分组数据
//Aggregation 接口的实现类,Terms 代表最基本的terms聚合
Terms sexValue = searchResponse.getAggregations().get("sexvalue");
//关闭ES客户端
esClient.close();
}
}
12:QueryBuilders.xxxx:简单查询
* BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //复合查询,可以兼容以下所有查询
* boolQueryBuilder.must(QueryBuilders.termQuery("falg","1")); //falg必须等于1
* boolQueryBuilder.mustNot(QueryBuilders.termQuery("delete,"1"));//delete必须不等于1
* boolQueryBuilder.should(QueryBuilders.wildcardQuery("name", "*jack*"));//可能名字中含有jack的文档
* QueryBuilders.matchAllQuery();查询全部
* QueryBuilders.matchQuery("name", "jack");match查询,会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到
* QueryBuilders.multiMatchQuery("music", "name", "interest");//搜索name中或interest中包含有music的文档(必须与music一致)
* QueryBuilders.wildcardQuery("name","*jack*");//搜索名字中含有jack文档(name中只要包含jack即可)
* QueryBuilders.matchPhraseQuery("name","张三");默认使用 match_phrase 时会精确匹配查询的短语,需要全部单词和顺序要完全一样,标点符号除外。
* QueryBuilders.termQuery(“name”,"张三");term 查询,精确的关键词匹配查询, 不对查询条件进行分词。
* RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
* rangeQueryBuilder.gte(12);
* rangeQueryBuilder.lte(12);
* gt表示大于;
* gte表示大于或等于;
* lt表示小于;
* lte表示小于或等于
12:searchSourceBuilder.xxxx:简单查询
* searchSourceBuilder.query();
* searchSourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("age","12")));
* searchSourceBuilder.aggregation()//
* AggregationBuilders.avg("avg_salary").field("salary");求平均值
* AggregationBuilders.max("max_salary").field("salary");求最大值
* AggregationBuilders.min("min_salary").field("salary");求最小值
* AggregationBuilders.sum("sum_salary").field("salary");求和
* AggregationBuilders.stats("stats_salary").field("salary");把上述的都查出来
* AggregationBuilders.range("age_ranges_count").field("age").addRange(0, 20).addRange(20, 40).addRange(40, 60);统计0-20岁,20-40岁,40~60岁各个区间段的员工人数
* AggregationBuilders.terms("age_count").field("age").size(3);根据年龄分组,统计相同年龄的用户,并只返回3条记录
* AggregationBuilders.dateRange("birthday_count").field("birthday").addRange("now/y-1y", "now/y").addRange("now/y-2y", "now/y-1y").addRange("now/y-3y", "now/y-2y").format("yyyy-MM-dd");统计生日在2017年、2018年、2019年的员工
* AggregationBuilders.histogram("age_histogram_count").field("age").interval(20);根据年龄间隔(20岁)统计各个年龄段的员工总人数
13:统计每年中用户的最高工资-嵌套查询
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构造请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//统计每年中用户的最高工资
DateHistogramAggregationBuilder dateHistogramAggregationBuilder = AggregationBuilders.dateHistogram("birthday_data_histogram_count")
.field("birthday")
.calendarInterval(DateHistogramInterval.YEAR)
.format("yyyy-MM-dd");
//嵌套子聚合查询
MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("max_salary")
.field("salary");
dateHistogramAggregationBuilder.subAggregation(maxAggregationBuilder);
searchSourceBuilder.aggregation(dateHistogramAggregationBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response;
try {
//发起请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//获取聚合的结果
Aggregations aggregations = response.getAggregations();
//Aggregation 接口的实现类,Histogram 代表直方图
Histogram aggregation = aggregations.get("birthday_data_histogram_count");
System.out.println(JSON.toJSONString(aggregation));
//获取桶聚合结果
List<? extends Histogram.Bucket> buckets = aggregation.getBuckets();
//循环遍历各个桶结果
for (Histogram.Bucket bucket : buckets) {
//分组的key
String key = bucket.getKeyAsString();
Aggregations subAggregations = bucket.getAggregations();
Aggregation maxSalaryAggregation = subAggregations.getAsMap().get("max_salary");
System.out.println(JSON.toJSONString(maxSalaryAggregation));
Map<String, Object> maxSalaryMap = (Map<String, Object>) JSONObject.parse(JSON.toJSONString(maxSalaryAggregation));
String maxSalary = null != maxSalaryMap.get("value") ? maxSalaryMap.get("value").toString() : "";
System.out.println(key + "------->" + maxSalary);
}
} catch (IOException e) {
e.printStackTrace();
}
//关闭ES客户端
restHighLevelClient.close();
}
14:统计每个年龄区间段的工资总和-嵌套查询
public static void main(String[] args) throws IOException {
//创建ES客户端
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//创建搜索对象
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
//构造请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//统计每年中用户的最高工资
DateRangeAggregationBuilder dateRangeAggregationBuilder = AggregationBuilders.dateRange("age_ranges_count")
.field("age")
.addRange(0, 20)
.addRange(20, 40)
.addRange(40, 60);
//嵌套子聚合查询
SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("sum_salary")
.field("salary");
dateRangeAggregationBuilder.subAggregation(sumAggregationBuilder);
searchSourceBuilder.aggregation(dateRangeAggregationBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response;
try {
//发起请求,获取响应结果
response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//获取聚合的结果
Aggregations aggregations = response.getAggregations();
//Aggregation 接口的实现类,Histogram 代表直方图
Histogram aggregation = aggregations.get("age_ranges_count");
System.out.println(JSON.toJSONString(aggregation));
//获取桶聚合结果
List<? extends Range.Bucket> buckets = ((Range) aggregation).getBuckets();
//循环遍历各个桶结果
for (Range.Bucket bucket : buckets) {
//分组的key
String key = bucket.getKeyAsString();
Aggregations subAggregations = bucket.getAggregations();
Aggregation maxSalaryAggregation = subAggregations.getAsMap().get("sum_salary");
System.out.println(JSON.toJSONString(maxSalaryAggregation));
Map<String, Object> sumSalaryMap = (Map<String, Object>) JSONObject.parse(JSON.toJSONString(maxSalaryAggregation));
String maxSalary = null != sumSalaryMap.get("value") ? sumSalaryMap.get("value").toString() : "";
System.out.println(key + "------->" + maxSalary);
}
} catch (IOException e) {
e.printStackTrace();
}
//关闭ES客户端
restHighLevelClient.close();
}
四:springboot中使用HighLevelClient 操作es
上述利用的是javase程序来进行测试的,但是我们现在环境基本都是springboot,实际上springboot环境下使用和上边是一样的,就是client客户端采用依赖注入的方式;
1:导包
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<!-- junit 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--lombok依赖-->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
2:配置config,链接es
package es.config;
import java.util.ArrayList;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig.Builder;
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.RestClientBuilder.RequestConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wkl
* @create 2022-06-28 18:46
*/
@Configuration
public class EsConfiguration {
private static String hosts = "192.168.62.145"; // 集群地址,多个用,隔开
private static int port = 9200; // 使用的端口号
private static String schema = "http"; // 使用的协议
private static ArrayList<HttpHost> hostList = null;
private static int connectTimeOut = 1000; // 连接超时时间
private static int socketTimeOut = 30000; // 连接超时时间
private static int connectionRequestTimeOut = 500; // 获取连接的超时时间
private static int maxConnectNum = 100; // 最大连接数
private static int maxConnectPerRoute = 100; // 最大路由连接数
private RestClientBuilder builder;
static {
hostList = new ArrayList<>();
String[] hostStrs = hosts.split(",");
for (String host : hostStrs) {
hostList.add(new HttpHost(host, port, schema));
}
}
@Bean
public RestHighLevelClient client() {
builder = RestClient.builder(hostList.toArray(new HttpHost[0]));
setConnectTimeOutConfig();
setMutiConnectConfig();
RestHighLevelClient client = new RestHighLevelClient(builder);
return client;
}
// 异步httpclient的连接延时配置
public void setConnectTimeOutConfig() {
builder.setRequestConfigCallback(new RequestConfigCallback() {
@Override
public Builder customizeRequestConfig(Builder requestConfigBuilder) {
requestConfigBuilder.setConnectTimeout(connectTimeOut);
requestConfigBuilder.setSocketTimeout(socketTimeOut);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
return requestConfigBuilder;
}
});
}
// 异步httpclient的连接数配置
public void setMutiConnectConfig() {
builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.setMaxConnTotal(maxConnectNum);
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
return httpClientBuilder;
}
});
}
}
3:配置config,链接es 集成账号密码
package com.wenge.talent.config;
import lombok.Data;
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.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.stream.Collectors;
@Configuration
@ConfigurationProperties(prefix = "spring.data.elasticsearch1")
@Data
public class EsConfigPass {
private List<EsConfig.HostPort> hostPorts;
@Data
static class HostPort {
private String host;
private int port;
}
/**
* 连接超时时间
*/
private int connectionTimeOut;
/**
* socket超时时间
*/
private int socketTimeOut;
/**
* 请求超时时间
*/
private int connectionRequestTimeOut;
/**
* 最大连接数
*/
private int maxConnectNum;
/**
* 最大路由连接数
*/
private int maxConnectNumPerRoute;
private String userName;
private String password;
@Bean
public RestHighLevelClient restHighLevelClient() {
//集群ip地址
HttpHost[] httpHosts = hostPorts.stream().map(i -> {
return new HttpHost(i.getHost(), i.getPort());
}).collect(Collectors.toList()).toArray(new HttpHost[hostPorts.size()]);
RestClientBuilder clientBuilder = RestClient.builder(httpHosts);
//账号密码
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
// 异步httpclient的连接延时配置
clientBuilder.setRequestConfigCallback((builder -> {
builder.setConnectTimeout(connectionTimeOut);
builder.setSocketTimeout(socketTimeOut);
builder.setConnectionRequestTimeout(connectionRequestTimeOut);
return builder;
})
);
// 异步httpclient的连接数配置
clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
httpAsyncClientBuilder.setMaxConnTotal(maxConnectNum);
httpAsyncClientBuilder.setMaxConnPerRoute(maxConnectNumPerRoute);
//账号密码
httpAsyncClientBuilder.disableAuthCaching();
httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
return httpAsyncClientBuilder;
});
return new RestHighLevelClient(clientBuilder);
}
}
3:依赖注入使用
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
/**
* @author wkl
* @create 2022-06-28 18:48
*/
public class Test {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建索引
* @param
* @throws IOException
*/
@Test
public void createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("六脉神剑");
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println("createIndex: " + JSON.toJSONString(createIndexResponse));
}
//请求数据工具方法
public SearchResponse searchRes(SearchSourceBuilder sourceBuilder,String indexName) throws IOException {
//查询数据,请求对象构造
SearchRequest request = new SearchRequest();
//索引名
request.indices(indexName);
//封装条件
request.source(sourceBuilder);
//查询请求
SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
return searchResponse;
}
//查询数据
public void testSearch(){
//构造请求体
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//构造组合查询请求体
BoolQueryBuilder query = QueryBuilders.boolQuery();
//过滤数据
query.must(QueryBuilders.termQuery("name","张"));
query.mustNot(QueryBuilders.termQuery("falg","1"));
//聚合分组查询
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("sexvalue").field("sex");
searchSourceBuilder.aggregation(aggregationBuilder);
searchSourceBuilder.query(query);
//分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(10);
//查询数据
SearchResponse searchResponse = null;
try {
searchResponse = this.searchRes(searchSourceBuilder,"myindex");
} catch (IOException e) {
System.out.println("查询数据失败:"+e.getMessage());
}
//构建返回数据
SearchHit[] hits = searchResponse.getHits().getHits();
//构建分组数据
Terms sexValue = searchResponse.getAggregations().get("sex");
}
}