目录
利用RestHighLevelClient客户端操作es查询文档
查询match_all
dsl语句:
编辑 java代码
小结
match字段全文检索查询
dsl语句
java代码
multi_match多字段全文检索查询
dsl语句
java代码
term精确查询
dsl语句
java代码
range范围查询
dsl语句
java代码
bool查询
dsl语句
java代码
算分查询
dsl语句
java代码
排序和分页
dsl语句
java代码
高亮显示
dsl语句
编辑 java代码
利用RestHighLevelClient客户端操作es查询文档
查询match_all
dsl语句:
java代码
-
第一步,创建
SearchRequest
对象,指定索引库名 -
第二步,利用
request.source()
构建DSL,DSL中可以包含查询、分页、排序、高亮等query()
:代表查询条件,利用QueryBuilders.matchAllQuery()
构建一个match_all查询的DSL
-
第三步,利用client.search()发送请求,得到响应
@SpringBootTest
public class TestSearch {
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 测试全文查询match_all
*/
@Test
public void test01() throws IOException {
//1.构建 查询对象
SearchRequest request = new SearchRequest("hotel");
//2.设置DSL语句
request.source().query(QueryBuilders.matchAllQuery());
//3.发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//4.解析数据
SearchHits hits = response.getHits();
//5.1 获取当前条件命中的文档数量
long value = hits.getTotalHits().value;
//5.2 获取命中的文档
SearchHit[] hitsHits = hits.getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
{
for (SearchHit hitsHit : hitsHits) {
String jsonData = hitsHit.getSourceAsString();
HotelDoc doc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(doc);
}
}
System.out.println(docs);
}
}
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结果,从外到内,逐层解析)
match字段全文检索查询
dsl语句
java代码
/**
* 单字段全文检索查询
*/
@Test
public void test02() throws IOException {
//构建 查询对象
SearchRequest request = new SearchRequest("hotel");
//设置DSL语句
//第一个参数是参与匹配的字段名,第二个参数是搜索内容
request.source().query(QueryBuilders.matchQuery("all","上海外滩"));
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHits hits = response.getHits();
long value = hits.getTotalHits().value;//获取命中文档数
SearchHit[] hitsHits = hits.getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hitsHit : hitsHits) {
String jsonData = hitsHit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
multi_match多字段全文检索查询
dsl语句
java代码
/**
* 多字段匹配查询
*/
@Test
public void test03() throws IOException {
//构建 搜索请求对象
SearchRequest request = new SearchRequest("hotel");
//设置DSL语句
request.source().query(QueryBuilders.multiMatchQuery("上海外滩","city","name","brand"));
//发送请求
SearchResponse response = restHighLevelClient.search(request,RequestOptions.DEFAULT);
//解析结果
SearchHits hits = response.getHits();
//获取命中结果数
long value = hits.getTotalHits().value;
//获取文档对象
SearchHit[] hitsHits = hits.getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hitsHit : hitsHits) {
String jsonData = hitsHit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
term精确查询
dsl语句
java代码
/**
* 精确查询
*/
@Test
public void test04() throws IOException {
//构建 搜索对象
SearchRequest request = new SearchRequest("hotel");
//设置DSL语句
request.source().query(QueryBuilders.termQuery("city","上海"));
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
range范围查询
dsl语句
java代码
/**
* range范围查询
*/
@Test
public void test05() throws IOException {
//构建 查询对象
SearchRequest request = new SearchRequest("hotel");
//设置dsl语句
request.source().query(QueryBuilders.rangeQuery("price").gte(200).lte(300));
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
bool查询
dsl语句
java代码
/**
* bool符合查询
*/
@Test
public void test06() throws IOException {
//构建 查询对象
SearchRequest request = new SearchRequest("hotel");
//设置dsl语句
//构建boolQuery对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.matchQuery("all","上海外滩"));
boolQuery.mustNot(QueryBuilders.rangeQuery("price").gte(500));
boolQuery.filter(QueryBuilders.geoDistanceQuery("location").distance("100km").point(31,121));
request.source().query(boolQuery);
//发送请求
SearchResponse response = restHighLevelClient.search(request,RequestOptions.DEFAULT);
//解析数据
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
算分查询
dsl语句
java代码
/**
* 算分查询
*/
@Test
public void test07() throws IOException {
//构建 查询对象
SearchRequest request = new SearchRequest("hotel");
//设置dsl语句
//定义算分函数
FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("brand","如家"),
ScoreFunctionBuilders.weightFactorFunction(10) // 权重因子,乘以基础得分
)
};
// 创建算分查询
QueryBuilders.functionScoreQuery(QueryBuilders.matchQuery("all","上海"),functions)
.boostMode(CombineFunction.MULTIPLY);
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//解析数据
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
排序和分页
dsl语句
java代码
/**
* 分页和排序
*/
@Test
public void test08() throws IOException {
//构建查询对象
SearchRequest request = new SearchRequest("hotel");
//设置dsl语句
request.source().query(QueryBuilders.matchQuery("all","酒店"));
// 添加基于地理位置的排序,假设我们根据"location"字段进行排序
GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", 31, 121)
.order(SortOrder.ASC) // 升序排序
.unit(DistanceUnit.KILOMETERS); // 单位为千米
request.source().sort(geoDistanceSortBuilder);
int page=1,size=5;
//es索引从0开始
request.source().from((page-1)*size).size(size);
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
docs.add(hotelDoc);
}
}
System.out.println(docs);
}
高亮显示
dsl语句
java代码
/**
* 分页和排序,高亮显示
*/
@Test
public void test09() throws IOException {
//构建查询对象
SearchRequest request = new SearchRequest("hotel");
//设置dsl语句
request.source().query(QueryBuilders.matchQuery("all","酒店"));
// 添加基于地理位置的排序,假设我们根据"location"字段进行排序
GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", 31, 121)
.order(SortOrder.ASC) // 升序排序
.unit(DistanceUnit.KILOMETERS); // 单位为千米
request.source().sort(geoDistanceSortBuilder);
int page=1,size=5;
//es索引从0开始
request.source().from((page-1)*size).size(size);
//设置高量
request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
//发送请求
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchHit[] hits = response.getHits().getHits();
ArrayList<HotelDoc> docs = new ArrayList<>();
if(ArrayUtils.isNotEmpty(hits)) {
for (SearchHit hit : hits) {
String jsonData = hit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
//获取高亮map集合
Map<String, HighlightField> fieldMap = hit.getHighlightFields();
if(!CollectionUtils.isEmpty(fieldMap)) {
//获取高亮字段name的值
HighlightField highlightField = fieldMap.get("name");
//获取name数组的第一个值
String hightName = highlightField.getFragments()[0].string();
//用高亮的值替换原来的值
hotelDoc.setName(hightName);
}
//获取排序的值
Object[] sortValues = hit.getSortValues();
System.out.println(Arrays.toString(sortValues));
docs.add(hotelDoc);
}
}
System.out.println(docs);
}