SpringBoot集成elasticsearch及常用api的使用方法
1.在Es官网找到你使用的es版本对应的Java Client的文档
官网地址:https://www.elastic.co/cn/
我这里以7.13.4为例
Es的依赖,建议使用
<!--注意在这里指定自己的es的版本--> <properties> <java.version>1.8</java.version> <elasticsearch.version>7.13.4</elasticsearch.version> </properties> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
Es的配置
2.找到es版本号,并指定es版本
3.示例代码
3.1.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.11.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.fast</groupId> <artifactId>spring-elastic-search</artifactId> <version>1.0.0</version> <name>spring-elastic-search</name> <description>连接es的demo</description> <properties> <java.version>1.8</java.version> <elasticsearch.version>7.13.4</elasticsearch.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--swagger文档依赖--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2.配置文件
package com.fast.config; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ElasticSearchClientConfig { @Bean public RestHighLevelClient restHighLevelClient() { RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.10.100", 32433, "http"))); return client; } }
3.3.yml配置文件
server: port: ${port:8083} spring: application: name: es knife4j: enable: true
3.4.测试类
package com.fast; import com.fast.entity.User; import lombok.extern.slf4j.Slf4j; import net.minidev.json.JSONValue; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.CreateIndexResponse; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import java.util.ArrayList; import java.util.Map; @SpringBootTest @Slf4j public class FastBootApplicationTest { @Autowired private RestHighLevelClient restHighLevelClient; //1.1创建索引(相当于Mysql创建数据库) @Test public void testCreateIndex() throws IOException { //1.创建索引请求 CreateIndexRequest request = new CreateIndexRequest("user"); //2.客户端执行请求IndicesClient,执行create方法创建索引,请求后获得响应 CreateIndexResponse response= restHighLevelClient.indices().create(request, RequestOptions.DEFAULT); System.out.println(response); } //1.2.判断索引是否存在 @Test public void testExistIndex() throws IOException { //1.查询索引请求 GetIndexRequest request=new GetIndexRequest("user"); //2.执行exists方法判断是否存在 boolean exists=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT); System.out.println(exists); } //1.3.删除索引 @Test public void testDeleteIndex() throws IOException { //1.删除索引请求 DeleteIndexRequest request=new DeleteIndexRequest("user"); //执行delete方法删除指定索引 AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT); System.out.println(delete.isAcknowledged()); } //2.1.新增文档(相当于MP的saveOrUpdate,不同之处在于若index不存在则会自动新增) @Test void testAddUser() throws IOException { //1.创建对象 User user = new User(1L,"张三1",23); //2.创建请求 IndexRequest request=new IndexRequest("user"); //3.设置规则 PUT /user/_doc/1 //设置文档id=6,设置超时=1s等,不设置会使用默认的,创建文档时若该ID已存在,发送创建文档请求后会更新文档中的数据。 //同时支持链式编程如 request.id("6").timeout("1s"); request.id("6"); request.timeout("1s"); //4.将数据放入请求,要将对象转化为json格式 //XContentType.JSON,告诉它传的数据是JSON类型 request.source(JSONValue.toJSONString(user), XContentType.JSON); //5.客户端发送请求,获取响应结果 IndexResponse indexResponse=restHighLevelClient.index(request,RequestOptions.DEFAULT); System.out.println(indexResponse.toString()); System.out.println(indexResponse.status()); } //3.1删除文档(根据文档_id删除,若不存在则返回NOT_FOUND) @Test public void testDeleteUser() throws IOException { //创建删除请求,指定要删除的索引与文档ID DeleteRequest request=new DeleteRequest("user","6"); DeleteResponse updateResponse=restHighLevelClient.delete(request,RequestOptions.DEFAULT); System.out.println(updateResponse); System.out.println(updateResponse.status());//删除成功返回OK,没有找到返回NOT_FOUND } //4.1.修改文档(文档_id不存在,返回修改失败;若某个属性不赋值,默认用null值覆盖,不会跳过值为null的字段) @Test public void testUpdateUser() throws IOException { //1.创建请求,指定索引、文档id UpdateRequest request=new UpdateRequest("user","6"); User user = new User(1L,"张三7"); //将创建的对象放入文档中 request.doc(JSONValue.toJSONString(user),XContentType.JSON); UpdateResponse updateResponse=restHighLevelClient.update(request,RequestOptions.DEFAULT); System.out.println(updateResponse); System.out.println(updateResponse.status());//更新成功返回OK } //5.1 根据文档_id获取数据 @Test public void testGetUser() throws IOException { //1.创建请求,指定索引、文档id GetRequest request=new GetRequest("user","6"); GetResponse getResponse=restHighLevelClient.get(request,RequestOptions.DEFAULT); System.out.println(getResponse);//获取响应结果,{"_index":"user","_type":"_doc","_id":"6","_version":2,"_seq_no":1,"_primary_term":1,"found":true,"_source":{"name":"张三1","id":1,"age":23}} System.out.println(getResponse.getSource()); //返回的是Map集合,{name=张三1, id=1, age=23} System.out.println(getResponse.getSourceAsString());//获取响应结果source中内容,转化为字符串,{"name":"张三1","id":1,"age":23} } //6.1.批量SaveOrUpdate数据(注意:false为执行成功,若文档id已存在,则修改;null值会覆盖,不会跳过) @Test public void testBulkAddUser() throws IOException { BulkRequest bulkRequest=new BulkRequest(); //设置超时 bulkRequest.timeout("10s"); ArrayList<User> list=new ArrayList<>(); list.add(new User(1L,"张三66"));//null值修改时会覆盖 list.add(new User(2L,"张三2",24)); list.add(new User(3L,"张三3",25)); list.add(new User(4L,"张三4",26)); list.add(new User(5L,"张三5",27)); int id=1; //批量处理请求 for (User u :list){ //不设置id会生成随机id bulkRequest.add(new IndexRequest("user") .id(""+(id++)) .source(JSONValue.toJSONString(u),XContentType.JSON)); } BulkResponse bulkResponse=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT); System.out.println(bulkResponse.hasFailures());//是否执行失败,false为执行成功 } //7.1.查询所有、模糊查询、分页查询、排序、高亮显示 @Test public void testSearch() throws IOException { SearchRequest searchRequest=new SearchRequest("user");//里面可以放多个索引 SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();//构造搜索条件 //此处可以使用QueryBuilders工具类中的方法 //1.查询所有 sourceBuilder.query(QueryBuilders.matchAllQuery()); //2.查询name中含有Java的 sourceBuilder.query(QueryBuilders.multiMatchQuery("张","name")); //3.分页查询 sourceBuilder.from(0).size(5); //4.按照score正序排列 //sourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC)); //5.按照id倒序排列(score会失效返回NaN) //sourceBuilder.sort(SortBuilders.fieldSort("_id").order(SortOrder.DESC)); //6.给指定字段加上指定高亮样式 HighlightBuilder highlightBuilder=new HighlightBuilder(); highlightBuilder.field("name").preTags("<span style='color:red;'>").postTags("</span>"); sourceBuilder.highlighter(highlightBuilder); searchRequest.source(sourceBuilder); SearchResponse searchResponse=restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT); //获取总条数 System.out.println(searchResponse.getHits().getTotalHits().value); //输出结果数据(如果不设置返回条数,大于10条默认只返回10条) SearchHit[] hits=searchResponse.getHits().getHits(); for(SearchHit hit :hits){ System.out.println("分数:"+hit.getScore()); Map<String,Object> source=hit.getSourceAsMap(); System.out.println("index->"+hit.getIndex()); System.out.println("id->"+hit.getId()); for(Map.Entry<String,Object> s:source.entrySet()){ System.out.println(s.getKey()+"--"+s.getValue()); } } } }
4.总结
4.1.大致流程
创建对应的请求 --> 设置请求(添加规则,添加数据等) --> 执行对应的方法(传入请求,默认请求选项)–> 接收响应结果(执行方法返回值)–> 输出响应结果中需要的数据(source,status等)
4.2.注意事项
- 如果不指定id,会自动生成一个随机id
- 正常情况下,不应该这样使用
new IndexRequest(“user”)
,如果索引发生改变了,那么代码都需要修改,可以定义一个枚举类或者一个专门存放常量的类,将变量用final static
等进行修饰,并指定索引值。其他地方引用该常量即可,需要修改也只需修改该类即可。 - elasticsearch相关的东西,版本都必须一致,不然会报错
- elasticsearch很消耗内存,建议在内存较大的服务器上运行elasticsearch,否则会因为内存不足导致elasticsearch自动killed