ES是一个**开源的高扩展的分布式全文搜索引擎,**是整个Elastic Stack技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。Elasticsearch软件是由Java语言开发的,所以也可以通过Java API的方式对Elasticsearch服务进行访问,并且操作的方式基本和Http操作一致
本文已经收录到我的Github: github.com/chenliang15…
Maven依赖
-
pom.xml
中加入ES需要的依赖<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> </dependencies> 复制代码
-
如果在运行时报错
java.lang.NoSuchMethodError: org.elasticsearch.client.Request.addParameters 复制代码
那么应该是发生了依赖冲突,新建一个Maven项目,最好不要直接创建springboot项目,可能会有依赖冲突,将上面的依赖加入到maven项目的pom中
链接ES客户端
因为使用的highLevel的ES客户端,所以可以很方便的连接到ES,只需要通过host和port就可以直接连接
public static void main(String[] args) throws IOException {
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
esClient.close();
}
复制代码
如果代码执行正常,没有报错那么就表示正常连接到了ES节点,可以通过获取到的RestHighLevelClient
对象进行操作
索引操作
加入了maven依赖,那么就可以通过Java客户端链接到ES进行操作,首先进行索引的基本操作
-
创建索引
RestHighLevelClient esClient = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http")) ); @Test public void index_create() throws IOException { // 创建索引 - 请求对象 CreateIndexRequest request = new CreateIndexRequest("test"); // 发送请求,获取响应 CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT); boolean acknowledged = response.isAcknowledged(); // 响应状态 System.out.println("操作状态 = " + acknowledged); } 复制代码
-
查询索引
RestHighLevelClient esClient = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http")) ); @Test public void index_get() throws IOException { GetIndexRequest request = new GetIndexRequest("test"); GetIndexResponse response = esClient.indices().get(request, RequestOptions.DEFAULT); System.out.println(Arrays.toString(response.getIndices())); System.out.println(response.getMappings()); System.out.println(response.getSettings()); } 复制代码
-
删除索引
RestHighLevelClient esClient = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http")) ); @Test public void index_delete() throws IOException { DeleteIndexRequest request = new DeleteIndexRequest("test"); AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT); System.out.println(response.isAcknowledged()); } 复制代码
文档操作
文档作为数据的对象,可以通过ES的客户端对象直接操作
RestHighLevelClient
对象和上面的创建方式相同,此处省略
文档基本操作
-
创建文档
@Test public void doc_create() throws IOException { IndexRequest request = new IndexRequest(); // 设置操作的索引和当前插入的文档的id request.index("people").id("1001"); User user = new User(); user.setName("张三"); user.setAge(10); user.setSex("男"); ObjectMapper mapper = new ObjectMapper(); String userJson = mapper.writeValueAsString(user); request.source(userJson, XContentType.JSON); IndexResponse response = esClient.index(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println("_index" + response.getIndex()); System.out.println("_id" + response.getId()); System.out.println("_result" + response.getResult()); } 复制代码
-
更新文档
@Test public void doc_update() throws IOException { UpdateRequest request = new UpdateRequest(); request.index("people").id("1001"); request.doc(XContentType.JSON, "sex", "女"); UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT); System.out.println(response); } 复制代码
-
查询文档
@Test public void doc_get() throws IOException { GetRequest request = new GetRequest(); request.index("people").id("1001"); GetResponse response = esClient.get(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println(response.getSource()); } 复制代码
-
删除文档
@Test public void doc_delete() throws IOException { DeleteRequest request = new DeleteRequest(); request.index("people").id("1001"); DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT); System.out.println(response); } 复制代码
文档批量操作
一般操作ES的数据都是批量保存或者批量删除,如果通过一条一条的操作,那么效率非常的低,可以通过批量操作API提高效率
-
批量保存
@Test public void doc_insert_batch() throws IOException { BulkRequest request = new BulkRequest(); request.add(new IndexRequest().index("people").id("1001").source(XContentType.JSON, "name", "张三", "sex", "男", "age", 10)); request.add(new IndexRequest().index("people").id("1002").source(XContentType.JSON, "name", "李四", "sex", "男", "age", 11)); request.add(new IndexRequest().index("people").id("1003").source(XContentType.JSON, "name", "王五", "sex", "男", "age", 12)); request.add(new IndexRequest().index("people").id("1004").source(XContentType.JSON, "name", "王五1", "sex", "男", "age", 8)); request.add(new IndexRequest().index("people").id("1005").source(XContentType.JSON, "name", "王五2", "sex", "男", "age", 9)); request.add(new IndexRequest().index("people").id("1006").source(XContentType.JSON, "name", "王五33", "sex", "男", "age", 7)); BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT); System.out.println(response.getTook()); System.out.println(Arrays.toString(response.getItems())); } 复制代码
-
批量删除
@Test public void doc_delete_batch() throws IOException { BulkRequest request = new BulkRequest(); request.add(new DeleteRequest().index("people").id("1001")); request.add(new DeleteRequest().index("people").id("1002")); request.add(new DeleteRequest().index("people").id("1003")); BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT); System.out.println(response.getTook()); System.out.println(response); } 复制代码
文档高级查询
高级查询、分组查询、分页、排序、聚合操作等,作为ES常用的查询操作,ES的Java客户端也提供了好用的API进行操作
-
查询指定索引的所有数据
@Test public void match_all() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchAllQuery()); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
term查询
@Test public void query_term() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.termQuery("age", 10)); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
分页查询
@Test public void query_page() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchAllQuery()); // from指定的是页数开始的偏移量, (当前页数 - 1)* size builder.from(0); builder.size(3); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
排序查询
@Test public void query_sort() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchAllQuery()); builder.sort("age", SortOrder.DESC); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
查询并过滤字段
@Test public void query_filter() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchAllQuery()); String[] excludes = {}; String[] includes = {"name"}; // 过滤字段,指定只包含某些字段,或者需要排除某些字段 builder.fetchSource(includes, excludes); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
bool条件查询,多条件Must
@Test public void query_bool_must() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // 多条件查询,must -> 一定需要匹配到 boolQueryBuilder.must(QueryBuilders.matchQuery("age", 10)); boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女")); builder.query(boolQueryBuilder); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
bool条件查询,多条件should
@Test public void query_bool_should() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); // 多条件查询,should -> 如果当前这条数据满足两个should条件中的任意一个,则表示满足条件 boolQueryBuilder.should(QueryBuilders.matchQuery("age", 10)); boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "女")); builder.query(boolQueryBuilder); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
范围查询
@Test public void query_range() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); // 根据某个字段构建范围查询 RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age"); // 指定范围查询的条件数据 rangeQueryBuilder.gte(9); rangeQueryBuilder.lte(12); builder.query(rangeQueryBuilder); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
模糊查询
@Test public void query_fuzzy() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); // 模糊查询,指定字段名称进行模糊查询,后面的指定模糊匹配的字符个数 builder.query(QueryBuilders.fuzzyQuery("name", "王五").fuzziness(Fuzziness.ONE)); request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("took:" + response.getTook()); System.out.println("timeout:" + response.isTimedOut()); System.out.println("total:" + hits.getTotalHits()); System.out.println("MaxScore:" + hits.getMaxScore()); System.out.println("hits========>>"); for (SearchHit hit : hits) { //输出每条查询的结果信息 System.out.println(hit.getSourceAsString()); } System.out.println("<<========"); } 复制代码
-
高亮查询
@Test public void query_highlight() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("sex", "女"); // 设置查询方式 builder.query(termsQueryBuilder); // 构建高亮字段 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags("<font color='red'>"); // 设置标签前缀 highlightBuilder.postTags("</font>"); // 设置标签后缀 highlightBuilder.field("sex"); // 设置高亮字段 // 设置高亮查询 builder.highlighter(highlightBuilder); // 设置请求体 request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response); SearchHits hits = response.getHits(); System.out.println("took::"+response.getTook()); System.out.println("time_out::"+response.isTimedOut()); System.out.println("total::"+hits.getTotalHits()); System.out.println("max_score::"+hits.getMaxScore()); System.out.println("hits::::>>"); for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); System.out.println(sourceAsString); //打印高亮结果 Map<String, HighlightField> highlightFields = hit.getHighlightFields(); System.out.println(highlightFields); } } 复制代码
-
聚合查询—最大值
@Test public void query_aggs_max() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); // 聚合查询,获取最大的age字段的数 builder.aggregation(AggregationBuilders.max("maxAge").field("age")); // 设置请求体 request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.println(response); } 复制代码
-
聚合查询—分组查询
@Test public void query_aggs_group() throws IOException { SearchRequest request = new SearchRequest(); request.indices("people"); SearchSourceBuilder builder = new SearchSourceBuilder(); // 聚合查询,获取最大的age字段的数 builder.aggregation(AggregationBuilders.terms("age_groupby").field("age")); // 设置请求体 request.source(builder); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); System.out.printl n(response); } 复制代码
文档的高级查询,JavaAPI的操作方式和语法基本和Http操作的一致,只不过将对应的Http方式替换为了API,可以更好的在程序中进行ES操作,下一篇一起看看如何在SpringBoot和ElasticSearch进行集成吧,更加方便的操作ES与索引数据
微信公众号「指尖上的代码」,欢迎关注~
原创不易, 点个赞再走呗~ 欢迎关注,给你带来更精彩的文章!
你的点赞和关注是写文章最大的动力~