内容简介: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封装笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hacking Growth
Sean Ellis、Morgan Brown / Crown Business / 2017-4-25 / USD 29.00
The definitive playbook by the pioneers of Growth Hacking, one of the hottest business methodologies in Silicon Valley and beyond. It seems hard to believe today, but there was a time when Airbnb w......一起来看看 《Hacking Growth》 这本书的介绍吧!