查询文档的基本步骤
- 1)准备Request对象
- 2)准备请求参数
- 3)发起请求
- 4)解析响应
示例解析
以match_all查询为例
代码解读:
- 第一步,创建SearchRequest对象,指定索引库名
- 第二步,利用request.source()构建DSL,DSL中可以包含查询、分页、排序、高亮等
- query():代表查询条件,利用QueryBuilders.matchAllQuery()构建一个match_all查询的DSL
- 第三步,利用client.search()发送请求,得到响应
这里关键的API有两个,一个是request.source(),其中包含了查询、排序、分页、高亮等所有功能:
另一个是QueryBuilders,其中包含match、term、function_score、bool等各种查询:
解析响应
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文档数据
小结
查询的基本步骤是:
- 创建SearchRequest对象
- 准备Request.source(),也就是DSL。
① QueryBuilders来构建查询条件
② 传入Request.source() 的 query() 方法 - 发送请求,得到结果
- 解析结果(参考JSON结果,从外到内,逐层解析)
代码示例
查询全部
点击查看代码
//查询全部
@Test
public void getAll() throws Exception{
// 1.准备Request
SearchRequest request = new SearchRequest("hotel");
// 2.准备DSL
request.source()
.query(QueryBuilders.matchAllQuery());
// 3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理结果
SearchHits responseHits = response.getHits();
long hitsTotalHits = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+hitsTotalHits+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
//遍历文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
match查询
点击查看代码
//match查询
@Test
public void match() throws Exception{
//准备request
SearchRequest request = new SearchRequest("hotel");
// 准备dsl语句
request.source().query(QueryBuilders.matchQuery("all","希尔顿"));
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 解析响应
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
精确查询
点击查看代码
@Test
public void term() throws Exception{
//准备request对象
SearchRequest request = new SearchRequest("hotel");
//准备dsl语句
request.source().query(QueryBuilders.termQuery("city","北京"));
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
范围查询
点击查看代码
//范围查询
@Test
public void range() throws Exception{
//准备request对象
SearchRequest request = new SearchRequest("hotel");
//准备dsl语句
request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
布尔查询
点击查看代码
//布尔查询
@Test
public void bool() throws Exception{
//准备request对象
SearchRequest request = new SearchRequest("hotel");
//准备dsl语句
//准备BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//添加term条件,城市必须在上海
boolQuery.must(QueryBuilders.termQuery("city","上海"));
//添加range条件,过滤掉价格在200元以上的
boolQuery.filter(QueryBuilders.rangeQuery("price").lte(200));
request.source().query(boolQuery);
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
排序,分页查询
点击查看代码
//排序,分页查询
@Test
public void sortAndPage() throws Exception{
// 页码,每页大小
int page = 1, size = 5;
//准备request对象
SearchRequest request = new SearchRequest("hotel");
//准备dsl语句
request.source().query(QueryBuilders.matchAllQuery());//查询
request.source().from((page - 1) * size).size(size);//分页
request.source().sort("price", SortOrder.ASC);//价格升序
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
}
}
高亮处理
点击查看代码
//高亮处理
@Test
public void highlight() throws Exception{
// 1.准备Request
SearchRequest request = new SearchRequest("hotel");
// 2.准备DSL
// 2.1.query
request.source().query(QueryBuilders.matchQuery("all", "如家"));
// 2.2.高亮
request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
// 3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
// 4.解析响应
SearchHits searchHits = response.getHits();
// 4.1.获取总条数
long total = searchHits.getTotalHits().value;
System.out.println("共搜索到" + total + "条数据");
// 4.2.文档数组
SearchHit[] hits = searchHits.getHits();
// 4.3.遍历
for (SearchHit hit : hits) {
// 获取文档source
String json = hit.getSourceAsString();
// 反序列化
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 --->" + hotelDoc);
}
}
坐标查询
点击查看代码
//根据坐标查询
@Test
public void geoDistance() throws Exception{
String location="31.21,121.5";
//准备request对象
SearchRequest request = new SearchRequest("hotel");
//准备dsl语句
request.source().sort(SortBuilders
.geoDistanceSort("location",new GeoPoint(location))
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS)
);
//发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits responseHits = response.getHits();
long total = responseHits.getTotalHits().value;//获取总条数
System.out.println("共获取数据"+total+"条");
SearchHit[] hits = responseHits.getHits();//文档数组
for (int i = 0; i < hits.length; i++) {
//获取文档的source
String json = hits[i].getSourceAsString();
//反序列化
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println("hotelDoc--->"+hotelDoc);
//获取距离值
Object[] sortValues = hits[i].getSortValues();
System.out.println("距离坐标距离--->"+sortValues[0]+"km");
}
}