在基本了解并在Kibana Dev Tools控制台操作Elasticsearch的查询语法之后,是时候在实际应用中使用ES了。那么怎么在Java中使用ES呢?
可以有下面几种方式来实现:
- Transport Client
- Java High Level REST Client
- Spring Data Elasticsearch
TransportClient
可用于老版本的Elasticsearch;新版本建议使用Java High Level REST Client
(向下兼容);当然还可以使用Spring Data提供的Spring Data Elasticsearch
。
本文先只介绍一下Transport Client
API,后面慢慢来REST Client
和Spring Data Elasticsearch
。
Transport Client
注意:在7.0.0中弃用。不推荐使用TransportClient,而推荐使用Java High Level REST Client,并将在Elasticsearch 8.0中将其删除。
Elasticsearch 8.x版本将会删除TransportClient
。这里为什么还要介绍一下它的API呢?毕竟有些老铁用的还是以前的版本,而且API很多地方是相通的,那就多学习一点吧!
引入jar包
代码语言:javascript复制<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.9.0</version>
</dependency>
注意版本号,一定要和你安装的Elasticsearch的版本号一致。
创建到ES的连接
必须得先连接到ES才能进行一系列的API测试,连接的代码如下:
代码语言:javascript复制// 创建连接
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(
new TransportAddress(
InetAddress.getByName("localhost"), 9300));
//一系列操作...
//关闭连接
client.close();
TransportClient
可以看到,
TransportClient
是deprecated,弃用了,我用的是ES 7.9版本,它在7.0.0中被弃用。
注意:
- InetAddress.getByName("localhost"), 9300) 这里绑定的端口9300是通讯端口,不是服务端口(服务端口是9200)
- 如果使用与“ elasticsearch”不同的集群名称,则必须设置集群名称:
Settings settings = Settings.builder()
.put("cluster.name", "myClusterName").build();
TransportClient client = new PreBuiltTransportClient(settings);
//Add transport addresses and do something with the client...
比如我的:
ES信息
单节点ES默认的集群名称就是elasticsearch
。
Index API
索引API允许将输入的JSON文档索引到特定索引中并使之可搜索。
生成JSON文档
生成JSON文档有很多种方法,比如:
- 手动构造
String json = "{"
""user":"kimchy","
""postDate":"2013-01-30","
""message":"trying out Elasticsearch""
"}";
- 使用Map
Map<String, Object> json = new HashMap<String, Object>();
json.put("user","kimchy");
json.put("postDate",new Date());
json.put("message","trying out Elasticsearch");
Map是一个key:values对集合。它可以表示一个JSON结构。
- Jackson
代码语言:javascript复制可以使用Jackson将bean序列化为JSON。
import com.fasterxml.jackson.databind.*;
// instance a json mapper
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
// generate json
byte[] json = mapper.writeValueAsBytes(yourbeaninstance);
- fastjson
代码语言:javascript复制com.alibaba.fastjson.JSONObject 它的转换方法,包括Java对象转成JSON串、JSON对象,JSON串转成java对象、JSON对象,JSON对象转换Java对象、JSON串等。
String stuString = "{"age":2,"name":"公众号行百里er","sex":"m"}";
//JSON字符串转换成JSON对象
JSONObject jsonObject1 = JSONObject.parseObject(stuString);
- 等等
当然,Elasticsearch也提供了内置的帮助器以生成JSON内容:
代码语言:javascript复制XContentBuilder builder = jsonBuilder()
.startObject()
.field("user", "kimchy")
.field("postDate", new Date())
.field("message", "trying out Elasticsearch")
.endObject()
增删改查API
Create 创建索引、文档相关API
向索引添加文档,如果索引不存在,则该API会自动给我们创建索引
代码语言:javascript复制@Test
@SneakyThrows
void esCRUD() {
// 创建连接
TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
.addTransportAddress(
new TransportAddress(
InetAddress.getByName("localhost"), 9300));
//增
create(client);
//查
//get(client);
//getAll(client);
//改
//update(client);
//删
//delete(client);
}
@SneakyThrows
void create(TransportClient client){
for (int i = 0; i < 5; i ) {
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("empName", "name" i)
.field("age", new Random().nextInt(100))
.field("createTime", new Date())
.endObject();
IndexResponse response = client.prepareIndex("emp", "_doc", String.valueOf(i))
.setSource(builder)
.get();
// //还可以不指定id
// IndexResponse response = client.prepareIndex("emp", "_doc")
// .setSource(builder)
// .get();
System.out.println(response.getResult());
}
}
这里我用prepareIndex指定id和不指定id分别执行了一遍,所以应该有10条文档产生。
通过Kibana控制台验证一下执行结果:
结果是执行成功的!
正好,用查询API来验证一下。
GET API 查询单个、所有文档相关API
代码生成的时候,又生成id为0~4的文档,就查一下id为3的吧先:
代码语言:javascript复制private void get(TransportClient client) {
GetResponse response = client.prepareGet("emp", "_doc", "3").get();
String index = response.getIndex();//获取索引名称
String type = response.getType();//获取索引类型
String id = response.getId();//获取索引id
System.out.println("index:" index);
System.out.println("type:" type);
System.out.println("id:" id);
System.out.println(response.getSourceAsString());
}
执行成功!
查询所有的API试一下:
代码语言:javascript复制private void getAll(TransportClient client) {
SearchResponse response = client.prepareSearch("emp").get();
SearchHits searchHits = response.getHits();
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
String res = hit.getSourceAsString();
System.out.println("res" res);
}
}
OK,成功查询出所有文档。
这里可以对比Kibana Dev Tools控制台返回的json结果,
代码语言:javascript复制{
"took" : 134,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "emp",
"_type" : "_doc",
"_id" : "ze2qFnQBZf6fz3EOVZFP",
"_score" : 1.0,
"_source" : {
"empName" : "name0",
"age" : 35,
"createTime" : "2020-08-22T14:54:54.999Z"
}
},
// 中间的结果略...
{
"_index" : "emp",
"_type" : "_doc",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"empName" : "name4",
"age" : 56,
"createTime" : "2020-08-22T15:05:58.480Z"
}
}
]
}
}
SearchResponse方法
Java API的一些方法名和ES查询结果JSON相关字段一般能对的上,如果平时控制台操作比较熟悉的话,再来使用API其实很简单了!
Update API
修改id为3的记录,将其name改为鲁班7号:
代码语言:javascript复制private void update(TransportClient client) {
try {
UpdateResponse response = client.prepareUpdate("emp", "_doc", "3")
.setDoc(XContentFactory.jsonBuilder()
.startObject()
.field("name", "鲁班7号")
.endObject())
.get();
System.out.println(response.getResult());
} catch (IOException e) {
e.printStackTrace();
}
}
验证一下:
Delete API
删除id为3的文档记录:
代码语言:javascript复制private void delete(TransportClient client) {
DeleteResponse response = client.prepareDelete("emp", "_doc", "3").get();
System.out.println(response.getResult());
}
小伙伴自己可以验证一下,没问题的!
看完点赞,养成习惯。举手之劳,赞有余香。