一.DSL查询分类
- 查询所有:查询出所有数据,一般测试用。例如:match_all
- 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
- match_query
- multi_match_query
- 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
- ids
- range
- term
- 地理(geo)查询:根据经纬度查询。例如:
- geo_distance
- geo_bounding_box
复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:
- bool
-
二:基本语法
match:根据一个字段查询
term:根据词条精确值查询
range:根据值的范围查询
geo_distance(附近查询): 查询到指定中心点小于某个距离值的所有文档。
fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名
bool query:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索
2.搜索结果处理
1.排序
elasticsearch默认是根据相关度算分排序的,可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
2.分页
from:从第几个文档开始 第几页
size:总共查询几个文档 每页显示多少条
3.高亮
步骤:
1.给文档中的所有关键字都添加一个标签,例如标签
2.页面给标签编写CSS样式
三.代码实现
准备客户端对象
private RestHighLevelClient client;
@BeforeEach
public void init() {
// 1.准备好Es的客户端对象
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.200.130:9200")
));
}
@AfterEach
public void tearDown() {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
1.查询
步骤:
1.创建请求
2.执行请求
3.解析响应结果
//查询全部
@Test
public void matchAll() throws IOException {
//1.创建请求
SearchRequest request = new SearchRequest("hotel");
SearchSourceBuilder source = request.source();
//1.1构建条件
source.query(QueryBuilders.matchAllQuery());
//2.执行请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//3.解析结果
printResult(response);
}
private void printResult(SearchResponse response) {
//3.解析结果
SearchHits hits = response.getHits();
System.out.println("查询到的文档数量:" + hits.getTotalHits().value);
//遍历
for (SearchHit searchHit : hits) {
String hotelJson = searchHit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(hotelJson, HotelDoc.class);
}
2.match查询
@Test
void testMatch() throws IOException {
// 1.准备Request
SearchRequest request = new SearchRequest("hotel");
// 2.准备DSL
request.source()
.query(QueryBuilders.matchQuery("all", "如家"));
// 3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
handleResponse(response);
}
3.精确查询
精确查询主要是两者:
- term:词条精确匹配
source.query(QueryBuilders.termQuery("city", "上海"));
range:范围查询
source.query(QueryBuilders.rangeQuery("price").gte(1000).lte(1500));
4.布尔查询
布尔查询是用must、must_not、filter等方式组合其它查询
/* * 布尔查询 * 包含: 上海外滩 * 价格 1000-1500 * 排除品牌 * */ @Test public void bool() throws IOException { //创建请求 SearchRequest request = new SearchRequest("hotel"); SearchSourceBuilder source = request.source(); //构建请求条件 //创建布尔条件 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); //组合其他基础条件 MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "上海外滩"); boolQuery.must(matchQueryBuilder); RangeQueryBuilder priceBuilder = QueryBuilders.rangeQuery("price").gte(1000).lte(1500); boolQuery.filter(priceBuilder); TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brand", "希尔顿"); boolQuery.mustNot(termQueryBuilder); source.query(boolQuery); //执行请求 SearchResponse search = client.search(request, RequestOptions.DEFAULT); //解析结果 printResult(search); }
5.排序、分页
```java public void sortAndPage() throws IOException {
//定义第几页 int page = 1; //定义每页显示多少条 int size = 3; //创建请求 SearchRequest request = new SearchRequest("hotel"); SearchSourceBuilder source = request.source(); //排序--->按照评价升序 source.sort("score", SortOrder.ASC); //评分一直,按照价格降序 source.sort("price", SortOrder.DESC); //分页 source.from((page - 1) * size); source.size(size); //执行请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); //解析结果 printResult(response);
}
<a name="wRHEr"></a>
## 6.高亮
高亮的代码与之前代码差异较大,有两点:
- 查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。
- 结果解析:结果除了要解析_source文档数据,还要解析高亮结果
**高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。**
```java
@Test
public void highlight() throws IOException {
//创建请求
SearchRequest request = new SearchRequest("hotel");
SearchSourceBuilder source = request.source();
//1.1构建条件
source.query(QueryBuilders.matchQuery("name", "外滩如家"));
//高亮条件设置
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name"); //那个字段高亮
highlightBuilder.preTags("<span>"); //前置标签
highlightBuilder.postTags("</span>"); //后置标签
source.highlighter(highlightBuilder);
//执行请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析结果
printResult(response);
}
解析结果
//解析结果
private void printResult(SearchResponse response) {
//3.解析结果
SearchHits hits = response.getHits();
System.out.println("查询到的文档数量:" + hits.getTotalHits().value);
//遍历
for (SearchHit searchHit : hits) {
String hotelJson = searchHit.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(hotelJson, HotelDoc.class);
//单独获取高亮处理结果
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
//判断
if (!CollectionUtils.isEmpty(highlightFields)) {
// 文档name字段的高亮处理结果
HighlightField highlightField = highlightFields.get("name");
//拼接高亮字段
String highlightResultStr = StringUtils.join(highlightField.getFragments());
//用高亮处理结果替换之前的name字段内容
hotelDoc.setName(highlightResultStr);
}
//输出文档
System.out.println(hotelDoc);
}
}