内容简介:pybbs5.0 框架用的还是spring-boot,但依赖的服务我都尽量的都分开了,比如发邮件,redis缓存等,这一篇来总结一下es的rest-client简单用法下面内容全部来自官方文档总结,地址:ES暴露给java的socket端口是9300,不过我这用的是 rest-client 的api,所以自然用的就是http协议的 9200端口了
pybbs5.0 框架用的还是spring-boot,但依赖的服务我都尽量的都分开了,比如发邮件,redis缓存等,这一篇来总结一下es的rest-client简单用法
下面内容全部来自官方文档总结,地址: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-maven.html
引入依赖
<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.5.3</version> </dependency> <!-- 高级api里有对文档,索引等的操作api,所以这里引入的是高级的api --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>6.5.3</version> </dependency>
连接ES服务
ES暴露给 java 的socket端口是9300,不过我这用的是 rest-client 的api,所以自然用的就是http协议的 9200端口了
RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http")));
创建索引
有了连接,首先要创建索引了,创建索引有两种方式的,一种是不带映射(mapping)的,一种是自定义映射的,下面代码展示
不带映射,让es自动识别字段的类型,并创建相应的映射
@Test public void createIndex() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); CreateIndexRequest request = new CreateIndexRequest("pybbs"); request.settings(Settings.builder() .put("index.number_of_shards", 1) .put("index.number_of_shards", 5)); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); log.info(response.toString()); System.out.println(response.isAcknowledged()); // 索引已经存在,则报错 }
自定义映射的索引 , 下面自定映射的field名的意思,移步我另一篇博客 https://tomoya92.github.io/2018/08/24/elasticsearch/ 里面有详细的解释
@Test public void createIndexWithMapping() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); CreateIndexRequest request = new CreateIndexRequest("pybbs"); request.settings(Settings.builder() .put("index.number_of_shards", 1) .put("index.number_of_shards", 5)); XContentBuilder mappingBuilder = JsonXContent.contentBuilder() .startObject() .startObject("properties") .startObject("title") .field("type", "text") .field("analyzer", "ik_max_word") .field("index", "true") .endObject() .startObject("content") .field("type", "text") .field("analyzer", "ik_max_word") // ik_max_word 这个分词器是ik的,可以去github上搜索安装es的ik分词器插件 .field("index", "true") .endObject() .endObject() .endObject(); request.mapping("topic", mappingBuilder); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); log.info(response.toString()); System.out.println(response.isAcknowledged()); }
验证映射存在
项目有时候会重启,不能每次重启都创建一次映射,这就需要用到判断映射是否存在了,存在就不创建了,不存在再创建,这样就不会报错了,具体代码如下
@Test public void existIndex() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); GetIndexRequest request = new GetIndexRequest(); request.indices("pybbs"); request.local(false); request.humanReadable(true); boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); log.info("result: {}", exists); }
删除映射
映射创建错了,要删除咋办,看下面
@Test public void deleteIndex() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); DeleteIndexRequest request = new DeleteIndexRequest("pybbs"); request.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT); log.info("result: {}", response.isAcknowledged()); }
创建/更新文档
有了映射,就可以创建文档了,下面先来创建一个简单的文档
@Test public void createDocument() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); Map<String, Object> map = new HashMap<>(); map.put("title", "上海自来水来自海上"); IndexRequest request = new IndexRequest("pybbs", "topic", "1"); // 这里最后一个参数是es里储存的id,如果不填,es会自动生成一个,个人建议跟自己的数据库表里id保持一致,后面更新删除都会很方便 request.source(map); IndexResponse response = client.index(request, RequestOptions.DEFAULT); // not exist: result: code: 201, status: CREATED // exist: result: code: 200, status: OK log.info("result: code: {}, status: {}", response.status().getStatus(), response.status().name()); }
如果创建文档自己指定id了,而且这个id已经在es里存在了,那么es会将这个id的数据执行更新操作,就是相当于更新数据了
不过更新文档也有自己的api,如下
@Test public void updateDocument() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); UpdateRequest request = new UpdateRequest("pybbs", "topic", "1"); Map<String, Object> map = new HashMap<>(); map.put("title", "title 22"); request.doc(map); UpdateResponse response = client.update(request, RequestOptions.DEFAULT); // exist: result: code: 200, status: OK // not exist: ERROR log.info("result: code: {}, status: {}", response.status().getStatus(), response.status().name()); }
从返回值看,更新的文档如果不存在的话,会报错,这样看来,还不如全都用创建文档的api了,如果文档不存在,它就直接创建了,不会报错
批量创建文档
一个一个的创建文档有些不爽,数据量大的时候,特别费时间,有没有批量的操作呢?有!
@Test public void bulkDocument() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); BulkRequest requests = new BulkRequest(); Map<String, Object> map1 = new HashMap<>(); map1.put("title", "我是中国人"); IndexRequest request1 = new IndexRequest("pybbs", "topic", "1"); request1.source(map1); requests.add(request1); Map<String, Object> map2 = new HashMap<>(); map2.put("title", "武汉市长江大桥欢迎您"); IndexRequest request2 = new IndexRequest("pybbs", "topic", "2"); request2.source(map2); requests.add(request2); Map<String, Object> map3 = new HashMap<>(); map3.put("title", "上海自来水来自海上"); IndexRequest request3 = new IndexRequest("pybbs", "topic", "3"); request3.source(map3); requests.add(request3); BulkResponse responses = client.bulk(requests, RequestOptions.DEFAULT); // not exist: result: code: 200, status: OK // exist: result: code: 200, status: OK log.info("result: code: {}, status: {}", responses.status().getStatus(), responses.status().name()); }
批量操作也跟创建文档一样,存在就更新,不存在就创建,不会报错
删除文档
上面说到的,最好自己指定id,不要让es自动生成id,这里就派上用场了
@Test public void deleteDocument() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); for (int i = 1; i <= 10; i++) { DeleteRequest request = new DeleteRequest("pybbs", "topic", String.valueOf(i)); DeleteResponse response = client.delete(request, RequestOptions.DEFAULT); // exist: result: code: 200, status: OK // not exist: result: code: 404, status: NOT_FOUND log.info("result: code: {}, status: {}", response.status().getStatus(), response.status().name()); } }
查询文档
前面做了那么多,就为了这一步,我上面给es安装了ik插件,所以这里对中文分词做个测试
先说明一下,查询的api有很多个 matchQuery()
termQuery()
fuzzyQuery()
等等,都啥意思,参见上面我另一篇博客的链接
@Test public void searchDocument() throws IOException { RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("localhost", 9200, "http"))); SearchRequest request = new SearchRequest("pybbs"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(QueryBuilders.matchQuery("title", "江大桥来自中国从武汉到上海喝中国人的自来水")); // builder.from(0).size(2); // 分页 request.source(builder); SearchResponse response = client.search(request, RequestOptions.DEFAULT); log.info(response.toString(), response.getTotalShards()); for (SearchHit documentFields : response.getHits()) { log.info("result: {}, code: {}, status: {}", documentFields.toString(), response.status().getStatus(), response.status().name()); } }
执行输出结果
09:42:47.766 YIIU [main] INFO co.yiiu.pybbs.PybbsApplicationTests - {"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":2.6610591,"hits":[{"_index":"pybbs","_type":"topic","_id":"3","_score":2.6610591,"_source":{"title":"上海自来水来自海上"}},{"_index":"pybbs","_type":"topic","_id":"2","_score":1.4384104,"_source":{"title":"武汉市长江大桥欢迎您"}},{"_index":"pybbs","_type":"topic","_id":"1","_score":1.4384104,"_source":{"title":"我是中国人"}}]}} 09:42:47.773 YIIU [main] INFO co.yiiu.pybbs.PybbsApplicationTests - result: { "_index" : "pybbs", "_type" : "topic", "_id" : "3", "_score" : 2.6610591, "_source" : { "title" : "上海自来水来自海上" } }, code: 200, status: OK 09:42:47.773 YIIU [main] INFO co.yiiu.pybbs.PybbsApplicationTests - result: { "_index" : "pybbs", "_type" : "topic", "_id" : "2", "_score" : 1.4384104, "_source" : { "title" : "武汉市长江大桥欢迎您" } }, code: 200, status: OK 09:42:47.773 YIIU [main] INFO co.yiiu.pybbs.PybbsApplicationTests - result: { "_index" : "pybbs", "_type" : "topic", "_id" : "1", "_score" : 1.4384104, "_source" : { "title" : "我是中国人" } }, code: 200, status: OK
结语
spring-boot不是都内置好了吗?只需要引个依赖,加几个注解就可以用了呀,为啥要自己费劲封装一遍呢?
目的就是为了跟spring-boot解耦,如果使用spring-boot内置的,引入依赖就要在 application.yml
里配置es服务的连接地址,但网站有时候不想开启es怎么办?每次启动就相当的麻烦了,所以分开操作才是王道
内置了确实对新手友好了,入门门坎低了,但相应的也带来了臃肿的体积,适当的折腾可以让程序更灵活,何乐而不为呢!
希望本篇博客能帮到正在折腾的你, 转载的请务必注明来源 ,谢谢!!
原文链接:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 封装JDBC—非框架开发必备的封装类
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
- docker 封装 alinode
- 封装Apk签名工具
- axios封装笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。