Elasticsearch8.8.0 全网最新版教程 从入门到精通 通俗易懂
配置项目
引入依赖
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.8.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.3</version></dependency><dependency><groupId>jakarta.json</groupId><artifactId>jakarta.json-api</artifactId><version>2.0.1</version></dependency>
添加配置文件
application.yaml
spring:elasticsearch:rest:scheme: httpshost: localhostport: 9200username: elasticpassword: 123456crt: classpath:ca.crt
导入ca证书到项目中
从任意一个es容器中,拷贝证书到resources目录下
/usr/share/elasticsearch/config/certs/ca
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXytUrDp-1691330960034)(media/16912196423122/16912204609393.jpg)]
添加配置
package com.lglbc.elasticsearch;import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.TransportUtils;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;import javax.net.ssl.SSLContext;
import java.io.IOException;/*** @Description TODO* @Author 关注公众号 “乐哥聊编程” 领取资料和源码 * @Date 2023/07/14 21:04*/
@Configuration
public class ElasticConfig {@Value("${spring.elasticsearch.rest.scheme}")private String scheme;@Value("${spring.elasticsearch.rest.host}")private String host;@Value("${spring.elasticsearch.rest.port}")private int port;@Value("${spring.elasticsearch.rest.crt}")private String crt;@Value("${spring.elasticsearch.rest.username}")private String username;@Value("${spring.elasticsearch.rest.password}")private String password;@Autowiredprivate ResourceLoader resourceLoader;@Beanpublic ElasticsearchClient elasticsearchClient() throws IOException {SSLContext sslContext = TransportUtils.sslContextFromHttpCaCrt(resourceLoader.getResource(crt).getFile());BasicCredentialsProvider credsProv = new BasicCredentialsProvider();credsProv.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));RestClient restClient = RestClient.builder(new HttpHost(host, port, scheme)).setHttpClientConfigCallback(hc -> hc.setSSLContext(sslContext).setDefaultCredentialsProvider(credsProv)).build();// Create the transport and the API clientElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());ElasticsearchClient client = new ElasticsearchClient(transport);return client;}
}
实战操作
创建mapping
@Testpublic void testCreateMapping() throws IOException {PutMappingRequest mappingRequest = new PutMappingRequest.Builder().index("lglbc_java_demo").properties("order_no", builder ->builder.keyword(type -> type)).properties("order_time", builder ->builder.date(type -> type.format("yyyy-MM-dd HH:mm:ss"))).properties("good_info", type -> type.nested(nested -> nested.properties("good_price", builder ->builder.double_(subType -> subType)).properties("good_count", builder ->builder.integer(subType -> subType)).properties("good_name", builder ->builder.text(subType ->subType.fields("keyword", subTypeField -> subTypeField.keyword(subSubType -> subSubType)))))).properties("buyer", builder ->builder.keyword(type -> type)).properties("phone", builder ->builder.keyword(type -> type)).build();ElasticsearchIndicesClient indices = elasticsearchClient.indices();if (indices.exists(request -> request.index("lglbc_java_demo")).value()) {indices.delete(request -> request.index("lglbc_java_demo"));}indices.create(request -> request.index("lglbc_java_demo"));indices.putMapping(mappingRequest);}
创建文档
@Testpublic void testAddData() throws IOException {OrderInfo orderInfo = new OrderInfo("1001", new Date(), "李白", "13098762567");List<OrderInfo.GoodInfo> goodInfos = new ArrayList<>();goodInfos.add(new OrderInfo.GoodInfo("苹果笔记本", 30.5d, 30));goodInfos.add(new OrderInfo.GoodInfo("苹果手机", 20.5d, 10));orderInfo.setGoodInfo(goodInfos);IndexRequest<OrderInfo> request = IndexRequest.of(i -> i.index("lglbc_java_demo").id(orderInfo.getOrderNo()).document(orderInfo));OrderInfo orderInfo2 = new OrderInfo("1002", new Date(), "苏轼", "13098762367");List<OrderInfo.GoodInfo> goodInfos2 = new ArrayList<>();goodInfos2.add(new OrderInfo.GoodInfo("华为笔记本", 18.5d, 15));goodInfos2.add(new OrderInfo.GoodInfo("苹果手机", 20.5d, 10));orderInfo2.setGoodInfo(goodInfos2);IndexRequest<OrderInfo> request2 = IndexRequest.of(i -> i.index("lglbc_java_demo").id(orderInfo2.getOrderNo()).document(orderInfo2));elasticsearchClient.index(request);elasticsearchClient.index(request2);}
查询更新
@Testpublic void testUpdateDataByQuery() throws IOException {UpdateByQueryRequest request = UpdateByQueryRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.term(term -> term.field("order_no").value("1001"))).script(script -> script.inline(inline -> inline.lang("painless").source("ctx._source['buyer'] = 'java 更新->乐哥聊编程'"))));elasticsearchClient.updateByQuery(request);}
全量更新
@Testpublic void testUpdateData() throws IOException {OrderInfo orderInfo3 = new OrderInfo("1002", new Date(), "苏轼3", "13098762367");List<OrderInfo.GoodInfo> goodInfos3 = new ArrayList<>();goodInfos3.add(new OrderInfo.GoodInfo("华为笔记本", 18.5d, 15));goodInfos3.add(new OrderInfo.GoodInfo("苹果手机", 20.5d, 10));orderInfo3.setGoodInfo(goodInfos3);UpdateRequest request = UpdateRequest.of(i -> i.index("lglbc_java_demo").id(orderInfo3.getOrderNo()).doc(orderInfo3));elasticsearchClient.update(request, OrderInfo.class);}
删除数据
@Testpublic void testDelete() throws IOException {DeleteRequest request = DeleteRequest.of(i -> i.index("lglbc_java_demo").id("1002"));elasticsearchClient.delete(request);}
批量操作(bulk)
@Testpublic void testBulkOperation() throws IOException {testCreateMapping();BulkRequest.Builder br = new BulkRequest.Builder();List<OrderInfo> orders = getOrders();for (OrderInfo orderInfo : orders) {br.operations(op -> op.index(idx -> idx.index("lglbc_java_demo").document(orderInfo)));}elasticsearchClient.bulk(br.build());}
基本搜索
@Testpublic void testBaseSearch() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.term(term -> term.field("order_no").value("1001"))));SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();List<OrderInfo> orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(JSONUtil.toJsonStr(orderInfos));}
复杂布尔搜索
@Testpublic void testBoolSearch() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.bool(bool -> bool.filter(filterQuery -> filterQuery.term(term -> term.field("buyer").value("李白"))).must(must -> must.term(term -> term.field("order_no").value("1004"))))));SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();List<OrderInfo> orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(JSONUtil.toJsonStr(orderInfos));}
嵌套(nested)搜索
@Testpublic void testNestedSearch() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.nested(nested -> nested.path("good_info").query(nestedQuery -> nestedQuery.bool(bool -> bool.must(must -> must.range(range -> range.field("good_info.good_count").gte(JsonData.of("16")))).must(must2 -> must2.range(range -> range.field("good_info.good_price").gte(JsonData.of("30")))))))));SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();List<OrderInfo> orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(JSONUtil.toJsonStr(orderInfos));}
分页查询
@Testpublic void testBasePageSearch() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").from(0).size(2).query(query -> query.matchAll(matchAll -> matchAll)));SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();List<OrderInfo> orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(orderInfos.size());request = SearchRequest.of(i -> i.index("lglbc_java_demo").from(2).size(2).query(query -> query.matchAll(matchAll -> matchAll)));response = elasticsearchClient.search(request, OrderInfo.class);hits = response.hits().hits();orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(orderInfos.size());request = SearchRequest.of(i -> i.index("lglbc_java_demo").from(4).size(2).query(query -> query.matchAll(matchAll -> matchAll)));response = elasticsearchClient.search(request, OrderInfo.class);hits = response.hits().hits();orderInfos = new ArrayList<>();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}System.out.println(orderInfos.size());}
滚动分页查询
@Testpublic void testScrollPageSearch() throws IOException {String scrollId = null;while (true) {List<OrderInfo> orderInfos = new ArrayList<>();if (StringUtils.isBlank(scrollId)) {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").scroll(Time.of(time -> time.time("1m"))).size(2).query(query -> query.matchAll(matchAll -> matchAll)));SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}scrollId = response.scrollId();} else {String finalScrollId = scrollId;ScrollRequest request = ScrollRequest.of(i -> i.scroll(Time.of(time -> time.time("1m"))).scrollId(finalScrollId));ScrollResponse response = elasticsearchClient.scroll(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());}scrollId = response.scrollId();}if (CollectionUtil.isEmpty(orderInfos)) {break;}System.out.println(orderInfos.size());}}
After分页查询
@Testpublic void testAfterPageSearch() throws IOException {final List<FieldValue>[] sortValue = new List[]{new ArrayList<>()};while (true) {List<OrderInfo> orderInfos = new ArrayList<>();SearchRequest request = SearchRequest.of(i -> {SearchRequest.Builder sort1 = i.index("lglbc_java_demo").size(2).sort(Lists.list(SortOptions.of(sort -> sort.field(field -> field.field("order_no").order(SortOrder.Desc)))));if (CollectionUtil.isNotEmpty(sortValue[0])) {sort1.searchAfter(sortValue[0]);}return sort1.query(query -> query.matchAll(matchAll -> matchAll));});SearchResponse<OrderInfo> response = elasticsearchClient.search(request, OrderInfo.class);List<Hit<OrderInfo>> hits = response.hits().hits();for (Hit hit : hits) {orderInfos.add((OrderInfo) hit.source());sortValue[0] = hit.sort();}if (CollectionUtil.isEmpty(orderInfos)) {break;}System.out.println(orderInfos.size());}}
词条(terms)聚合
@Testpublic void testTermsAgg() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.matchAll(match->match)).aggregations("agg_term_buyer",agg->agg.dateHistogram(dateHistogram->dateHistogram.field("order_time").calendarInterval(CalendarInterval.Day))));SearchResponse<Void> search = elasticsearchClient.search(request, Void.class);Map<String, Aggregate> aggregations = search.aggregations();Aggregate aggregate = aggregations.get("agg_term_buyer");Buckets<StringTermsBucket> buckets = ((StringTermsAggregate) aggregate._get()).buckets();for (StringTermsBucket bucket : buckets.array()) {String key = bucket.key()._toJsonString();long l = bucket.docCount();System.out.println(key+":::"+l);}}
日期聚合
@Testpublic void testDateAgg() throws IOException {SearchRequest request = SearchRequest.of(i -> i.index("lglbc_java_demo").query(query -> query.matchAll(match->match)).aggregations("agg_date_buyer",agg->agg.dateHistogram(dateHistogram->dateHistogram.field("order_time").calendarInterval(CalendarInterval.Day))));SearchResponse<Void> search = elasticsearchClient.search(request, Void.class);Map<String, Aggregate> aggregations = search.aggregations();Aggregate aggregate = aggregations.get("agg_date_buyer");List<DateHistogramBucket> buckets = ((DateHistogramAggregate) aggregate._get()).buckets().array();System.out.println(aggregate);for (DateHistogramBucket bucket : buckets) {String key = bucket.keyAsString();long l = bucket.docCount();System.out.println(key+":::"+l);}}