[微服务]RestClient客户端
快速入门
使用RestClient客户端进行数据搜索可以分为两步
- 构建并发起请求
代码解读:
- 第一步,创建
SearchRequest
对象,指定索引库名 - 第二步,利用
request.source()
构建DSL,DSL中可以包含查询、分页、排序、高亮等
-
query()
:代表查询条件,利用QueryBuilders.matchAllQuery()
构建一个match_all
查询的DSL
- 第三步,利用
client.search()
发送请求,得到响应
核心步骤:
- 这里关键的API有两个,一个是
request.source()
,它构建的就是DSL中的完整JSON参数。其中包含了query
、sort
、from
、size
、highlight
等所有功能:
- 另一个是
QueryBuilders
,其中包含了我们学习过的各种叶子查询、复合查询等:
- 解析查询结果
elasticsearch返回的结果是一个JSON字符串,结构包含:
hits
:命中的结果
-
total
:总条数,其中的value是具体的总条数值max_score
:所有结果中得分最高的文档的相关性算分hits
:搜索结果的文档数组,其中的每个文档都是一个json对象
-
-
_source
:文档中的原始数据,也是json对象
-
因此,我们解析响应结果,就是逐层解析JSON字符串,流程如下:
SearchHits
:通过response.getHits()
获取,就是JSON中的最外层的hits
,代表命中的结果
-
SearchHits#getTotalHits().value
:获取总条数信息SearchHits#getHits()
:获取SearchHit
数组,也就是文档数组
-
-
SearchHit#getSourceAsString()
:获取文档结果中的_source
,也就是原始的json
文档数据
-
示例
- 新建测试类
public class ElasticSearchTest {
private RestHighLevelClient client;
@Test
void test() {
System.out.println("client =" + client);
}
@BeforeEach
void setup() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.1.97:9200")
));
}
@AfterEach
void tearDown() throws IOException {
if (client != null) {
client.close();
}
}
}
- 创建并发送请求, 解析结果
public class ElasticSearchTest {
private RestHighLevelClient client;
@Test
void test() {
System.out.println("client =" + client);
}
@Test
void testMatchAll() throws IOException {
//1.创建request对象
SearchRequest request = new SearchRequest("items");
//2.配置request参数
request.source()
.query(QueryBuilders.matchAllQuery());
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("response = " + response);
//4.解析结果
SearchHits searchHits = response.getHits();
// 总条数
long total = searchHits.getTotalHits().value;
System.out.println("total = " + total);
// 命中的数据
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
// 获取source结果
String json = hit.getSourceAsString();
// 转为ItemDoc
ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);
System.out.println("doc = " + doc);
}
}
@BeforeEach
void setup() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.1.97:9200")
));
}
@AfterEach
void tearDown() throws IOException {
if (client != null) {
client.close();
}
}
}
- 执行结果
构建查询条件
全文检索的查询条件构造API如下
精确查询的查询条件构造API如下:
布尔查询的查询条件构造API如下:
构建复杂查询条件的搜索
需求: 利用lavaRestClient实现搜索功能, 条件如下
- 搜索关键字为脱脂牛奶
- 品牌必须为德亚
- 价格必须低于300
public class ElasticSearchTest {
private RestHighLevelClient client;
@Test
void test() {
System.out.println("client =" + client);
}
@Test
void testSearch() throws IOException {
//1.创建request对象
SearchRequest request = new SearchRequest("items");
//2.组织DSL参数
request.source().query(
QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", "脱脂牛奶"))
.filter(QueryBuilders.termQuery("brand", "德亚"))
.filter(QueryBuilders.rangeQuery("price").lt(3000))
);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println("response = " + response);
//4.解析结果
parseResponseResult(response);
}
private void parseResponseResult(SearchResponse response) {
//4.解析结果
SearchHits searchHits = response.getHits();
// 总条数
long total = searchHits.getTotalHits().value;
System.out.println("total = " + total);
// 命中的数据
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
// 获取source结果
String json = hit.getSourceAsString();
// 转为ItemDoc
ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);
System.out.println("doc = " + doc);
}
}
@BeforeEach
void setup() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.1.97:9200")
));
}
@AfterEach
void tearDown() throws IOException {
if (client != null) {
client.close();
}
}
}
排序和分页
与query类似,排序和分页参数都是基于request.source()来设置:
public class ElasticSearchTest {
private RestHighLevelClient client;
@Test
void test() {
System.out.println("client =" + client);
}
@Test
void testSortAndPage() throws IOException {
// 模拟前端分页参数
int pageNo = 1, pageSize = 5;
//1.创建request对象
SearchRequest request = new SearchRequest("items");
//2.组织DSL条件
//2.1query条件
request.source().query(
QueryBuilders.matchAllQuery()
);
//2.2.分页条件
request.source().from((pageNo - 1) * pageSize).size(pageSize);
//2.3 排序条件
request.source()
.sort("sold", SortOrder.DESC)
.sort("price",SortOrder.ASC);
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析结果
parseResponseResult(response);
}
private void parseResponseResult(SearchResponse response) {
//4.解析结果
SearchHits searchHits = response.getHits();
// 总条数
long total = searchHits.getTotalHits().value;
System.out.println("total = " + total);
// 命中的数据
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
// 获取source结果
String json = hit.getSourceAsString();
// 转为ItemDoc
ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);
System.out.println("doc = " + doc);
}
}
@BeforeEach
void setup() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.1.97:9200")
));
}
@AfterEach
void tearDown() throws IOException {
if (client != null) {
client.close();
}
}
}
高亮展示
高亮显示的条件构造API如下
高亮显示的结果解析API如下:
示例
public class ElasticSearchTest {
private RestHighLevelClient client;
@Test
void test() {
System.out.println("client =" + client);
}
@Test
void testHighLight() throws IOException {
//1.创建request对象
SearchRequest request = new SearchRequest("items");
//2.组织DSL条件
//2.1query条件
request.source().query(
QueryBuilders.matchQuery("name", "脱脂牛奶")
);
//2.2.高亮条件
request.source().highlighter(SearchSourceBuilder.highlight().field("name"));
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.解析结果
parseResponseResult(response);
}
private void parseResponseResult(SearchResponse response) {
//4.解析结果
SearchHits searchHits = response.getHits();
// 总条数
long total = searchHits.getTotalHits().value;
System.out.println("total = " + total);
// 命中的数据
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : hits) {
// 获取source结果
String json = hit.getSourceAsString();
// 转为ItemDoc
ItemDoc doc = JSONUtil.toBean(json, ItemDoc.class);
// 按需处理高亮结果
Map<String, HighlightField> hfs = hit.getHighlightFields();
if (hfs != null && !hfs.isEmpty()) {
// 根据高亮字段名获取高亮结果
HighlightField hf = hfs.get("name");
// 获取高亮结果, 覆盖非高亮结果
String name = hf.fragments()[0].string();
doc.setName(name);
}
System.out.println("doc = " + doc);
}
}
@BeforeEach
void setup() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.1.97:9200")
));
}
@AfterEach
void tearDown() throws IOException {
if (client != null) {
client.close();
}
}
}