Java中API查询文档
Elasticsearch在网页端查询文档对应的DSL语句如下:
GET /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
},
"highlight": {
"fields": {
"name": {
"require_field_match": "false"
}
}
}
}
执行上述语句打印结果如下:
在Java代码中我们需要准备request,DSL语句以及发送请求
private RestHighLevelClient client;
@Test
void testMatchAll() throws IOException {
//准备request
SearchRequest request = new SearchRequest("hotel");//hotel为我们之前文章中所建立的索引库
//准备DSL语句,查询所有文档
request.source().query(QueryBuilders.matchAllQuery());
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//打印结果
System.out.println(response);
}
@BeforeEach
void setUp() {
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.220.***:9200")
));
}
@AfterEach
void tearDown() throws IOException {
client.close();
}
}
如下图所示,打印除开的结果为String类型,可以优化为HotelDoc对象类型。
其对应的Java代码改进后如下,以下的步骤是根据上面网页端响应出来的结果由外到内逐层解析出来的,相关详细注释如下:
@Test
void testMatchAll() throws IOException {
//准备request
SearchRequest request = new SearchRequest("hotel");
//准备DSL语句
request.source().query(QueryBuilders.matchAllQuery());
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析响应结果,对于网页端的hits,参考json解析结果由外到内逐层解析
SearchHits searchHits = response.getHits();
//获取命中的总条数
TotalHits total = searchHits.getTotalHits();
//打印搜索出多少条数据
System.out.println("共搜索出"+total+"条数据");
//搜索出的文档数组
SearchHit[] hits = searchHits.getHits();
//遍历文档数组
for (SearchHit hit : hits) {
//获取文档source
String json = hit.getSourceAsString();
//反序列为HotelDoc对象
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//打印输出
System.out.println(hotelDoc);
}
执行上述代码所得结果如下,已反序列化为HotelDoc对象:
部分小结:
RestAPI其中构建DSL是通过RestHighLevelClient的source()方法实现的,如同我们浏览器中json中写的方法,其包含很多功能,如排序,分页,高亮等:
RestAPI中构建查询条件的核心部分是由QueryBuilders工具类提供的,其中包含了很多种查询方法。
全文查询
全文检索查询的match和multi_match查询与match_all的API基本一致,主要就是query部分的查询条件不一致,例如:
//这里的all是整合了需要查询的组合字段,在建立索引库时候添加的
request.source().query(QueryBuilders.matchQuery("all", "如家"));
1
2
除了此处不一致以外,其他代码均与上面一致
精确查询
精确查询常见的有term查询和range查询,可以使用QueryBuilders工具类来实现。
例如基于词条查询和范围查询的DSL语句如下:
# 词条查询
GET /hotel/_search
{
"query": {
"term": {
"city": "上海"
}
}
}
# 范围查询
GET /hotel/_search
{
"query": {
"range": {
"price": {
"gte": 100,
"lte": 200
}
}
}
}
使用QueryBuilders工具类来实现的代码如下:
request.source().query(QueryBuilders.termQuery("city","上海"));
1
request.source().query(QueryBuilders.rangeQuery("price").gt(150).lt(200));
1
复合查询
例如使用term查询和range查询组合到一起来进行组合查询,在DSL中的语句为:
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"city": {
"value": "上海"
}
}
}
],
"filter": [
{
"range": {
"price": {
"gte": 150,
"lte": 200
}
}
}
]
}
}
}
将其转化为Java语言中的代码,如下:
//准备DSL语句
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.termQuery("city","上海"));
boolQuery.filter(QueryBuilders.rangeQuery("price").gt(150).lt(200));
request.source().query(boolQuery);
执行代码得到以下结果:
排序和分页
对搜索的结果进行排序和分页,是与query同级的参数,由以下的DSL语句可以看出:
GET /hotel/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5
, "sort": [
{
"price": {
"order": "desc"
}
}
]
}
上面DSL对于的Java代码如下,query和sort等为同级结构:
//准备DSL语句
request.source().query(QueryBuilders.matchAllQuery());
request.source().from(0).size(5);//查询结果显示五条数据
request.source().sort("price", SortOrder.ASC);//按照升序的顺序排列
执行结果如下:
高亮显示
高亮API包括请求DSL构建和结果解析两部分,DSL语句如下:
GET /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
},
"highlight": {
"fields": {
"name": {
"require_field_match": "false"
}
}
}
}
网页端高亮显示结果如下图所示:
Java代码如下:
@Test
void testHighLighter() throws IOException {
//准备request
SearchRequest request = new SearchRequest("hotel");
//准备DSL语句
request.source().query(QueryBuilders.matchQuery("name","如家"));
request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析响应结果,对于网页端的hits,参考json解析结果由外到内逐层解析
handleResponse(response);
}
private void handleResponse(SearchResponse response) {
//解析响应结果,对于网页端的hits,参考json解析结果由外到内逐层解析
SearchHits searchHits = response.getHits();
//获取命中的总条数
TotalHits total = searchHits.getTotalHits();
//打印搜索出多少条数据
System.out.println("共搜索出" + total + "条数据");
//搜索出的文档数组
SearchHit[] hits = searchHits.getHits();
//遍历文档数组
for (SearchHit hit : hits) {
//获取文档source
String json = hit.getSourceAsString();
//反序列为HotelDoc对象
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//获取高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
//如果高亮结果不为空才设置值
if(!CollectionUtils.isEmpty(highlightFields)){
//根据字段名称获取高亮结果
HighlightField highlightField = highlightFields.get("name");
if(highlightField!=null){
//获取高亮值
String name = highlightField.getFragments()[0].string();
//覆盖非高亮结果
hotelDoc.setName(name);
}
}
//打印输出
System.out.println(hotelDoc);
}
}
写了这么多API的使用”,感觉大佬如果看完的话会稍微有些累哈哈。
好了,本篇文章就先分享到这里了,后续会继续分享其他方面的知识,感谢大佬认真读完支持咯~
免责申明:
本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!
《数据治理行业实践白皮书》下载地址:https://fs80.cn/4w2atu
《数栈V6.0产品白皮书》下载地址:https://fs80.cn/cw0iw1
想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=bbs
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术群」,交流最新开源技术信息,群号码:30537511,项目地址:https://github.com/DTStack