Java判断上海自来水来自海上_Elasticsearch6.5.3 rest-client 用法封装

pybbs5.0 框架用的还是spring-boot,但依赖的服务我都尽量的都分开了,比如发邮件,redis缓存等,这一篇来总结一下es的rest-client简单用法

引入依赖

org.elasticsearch

elasticsearch

6.5.3

org.elasticsearch.client

elasticsearch-rest-high-level-client

6.5.3

连接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()); // 索引已经存在,则报错

}

@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 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 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 map1 = new HashMap<>();

map1.put("title", "我是中国人");

IndexRequest request1 = new IndexRequest("pybbs", "topic", "1");

request1.source(map1);

requests.add(request1);

Map map2 = new HashMap<>();

map2.put("title", "武汉市长江大桥欢迎您");

IndexRequest request2 = new IndexRequest("pybbs", "topic", "2");

request2.source(map2);

requests.add(request2);

Map 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怎么办?每次启动就相当的麻烦了,所以分开操作才是王道

内置了确实对新手友好了,入门门坎低了,但相应的也带来了臃肿的体积,适当的折腾可以让程序更灵活,何乐而不为呢!

希望本篇博客能帮到正在折腾的你, 转载的请务必注明来源

,谢谢!!

原文链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值