一、Elasticsearch的DSL
1.1 DSL Query的分类
Elasticsearch提供了基于JSON的DSL来定义查询。常见的查询类型包括:
-
查询所有:查询出所有数据,一般测试用。例如:
- match_all:匹配所有文档并返回它们;
-
全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
- match_query:针对单个字段执行全文本查询;
- multi_match_query:针对多个字段执行全文本查询的一种查询;
-
精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:
- ids:查询指定的一组文档,基于它们的ID进行匹配;
- range:用于执行范围查询的查询,可以匹配一个数字或日期字段的范围;
- term:对查询字符串不进行分词,直接与指定的字段进行比较;
-
地理(geo)查询:根据经纬度查询。例如:
-
geo_distance:查找与指定地理位置之间的距离在一定范围内的文档的查询;
格式:
{ "geo_distance": { "distance": "范围", "包含地理位置信息的字段名称": { "lat": 中心点的纬度, "lon": 中心点的经度 } } }
-
geo_bounding_box:查找落在指定矩形框中的文档的查询;
格式:
{ "geo_bounding_box": { "包含地理位置信息的字段名称": { "top_left": { "lat": 左上角顶点的纬度, "lon": 左上角顶点的经度 }, "bottom_right": { "lat": 右下角顶点的纬度, "lon": 右下角顶点的经度 } } } }
-
-
复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:
-
bool:将多个查询组合起来的查询方式;
格式:
{ "bool": { "must": [要执行的查询语句], "should": [要执行的查询语句], "must_not": [要执行的查询语句], "filter": 过滤函数 } }
- must:必须匹配每个子查询
- should:选择性匹配子查询
- must_not:必须不匹配,不参与算分
- filter:必须匹配,不参与算分
-
function_score:在查询结果的排序过程中,根据指定的函数对文档进行打分的查询;
格式:
{ "function_score": { "query": 要执行的查询语句, "functions": [要执行的函数列表], "boost_mode": "函数得分的模式", "score_mode": "指定如何处理不同函数之间得分的模式" } }
-
查询语法:
GET /索引库名/_search
{
"query": {
"查询类型": {
"查询条件": "条件值"
}
}
}
1.2 搜索结果处理
排序:
-
基于字段排序:
格式:
{ "query": { "match_all": {} }, "sort": [ { "排序字段": "排序规则" } ] }
排序规则:asc正序、desc倒序
-
基于地理位置排序
格式:
{ "query": { "match_all": {} }, "sort": [ { "_geo_distance": { "坐标字段": { "lat": 维度值, "lon": 经度值 }, "order": "排序规则", "unit": "单位" } } ] }
分页:
Elasticsearch在默认情况下只会返回10条数据,故如果需要查询更多数据就需要对分页参数进行配置;
{
"query": {
"match_all": {}
},
"from": 起始文档,
"size": 显示的文档数量
}
高亮:
require_field_match:字段匹配,结果值为true则只有与搜索字段相同的字段才会高亮,默认为true;
{
"query": {
"match": {
"搜索字段": "关键字"
}
},
"highlight": {
"fields": {
"设置高亮的字段": {
"pre_tags": "标记高亮的前置标签",
"post_tags": "标记高亮的后置标签",
"require_field_match": "false"
}
}
}
}
二、DSL在RestClient中的使用
1.1 查询语法
@Test
void testMathAll() throws IOException {
//1.准备Request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
request.source().query(查询构造器);
//3.发送请求
client.search(request, RequestOptions.DEFAULT);
//4.解析结果
SearchHits searchHits = response.getHits();
//4.1 查询总条数
long total = searchHits.getTotalHits().value;
//4.2 查询的结果数组
SearchHit[] hits = searchHits.getHits();
}
部分查询构造器:
- matchQuery:构建一个匹配查询,可以匹配文本、数字、日期等类型的数据。示例代码:
QueryBuilder query = QueryBuilders.matchQuery("搜索字段", "搜索词");
- matchAllQuery:构建一个查询所有。示例代码:
QueryBuilder query = QueryBuilders.QueryBuilders.matchAllQuery();
- rangeQuery:构建一个范围查询,可以匹配数值、日期等范围内的数据。示例代码:
QueryBuilder query = QueryBuilders.rangeQuery("搜索字段").from(下限).to(上限);
- termQuery:构建一个精确匹配查询,可以精确匹配某个字段的值。示例代码:
QueryBuilder query = QueryBuilders.termQuery("搜索字段", "搜索词");
- fuzzyQuery:构建一个模糊查询,可以模糊匹配某个字段的值。示例代码:
QueryBuilder query = QueryBuilders.fuzzyQuery("搜索字段", "搜索词");
- boolQuery:构建一个布尔查询,可以通过must、should、mustNot等条件来组合查询。示例代码:
QueryBuilder query = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("搜索字段", "搜索词"))
.should(QueryBuilders.termQuery("搜索字段", "搜索词"))
.mustNot(QueryBuilders.rangeQuery("搜索字段").gte(下限).lte(上限));
1.2 matchQuery和fuzzyQuery的区别
matchQuery和fuzzyQuery都是Elasticsearch中的查询方式,但它们有以下不同点:
- 分词处理:matchQuery会对查询的关键字进行分词处理,而fuzzyQuery不会进行分词处理。
- 匹配规则:matchQuery会将查询关键字与文档中所有分词进行匹配,并且可以通过设置operator参数来指定匹配规则,如AND或OR。而fuzzyQuery可以进行模糊匹配,可以匹配到与查询关键字相似的文档。
- 匹配精度:matchQuery是精确匹配,只能匹配到与查询关键字完全相等的文档。而fuzzyQuery是近似匹配,可以通过设置fuzziness参数来指定允许的编辑距离,从而匹配到与查询关键字相似的文档。
- 数据类型:matchQuery适用于text类型的字段,而fuzzyQuery也适用于text类型的字段,通常用于匹配拼写错误的单词。
1.3 排序和分页
使用查询API和分页/排序API来实现查询结果的排序和分页操作。
- 排序操作:
可以通过在查询API中指定sort参数来对查询结果进行排序,示例代码如下:
SearchRequest searchRequest = new SearchRequest("my_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.sort(new FieldSortBuilder("create_time").order(SortOrder.DESC));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);
上述代码中,在查询API中指定了sort参数,以create_time
字段进行排序,并指定了排序方式为降序。这样查询出来的结果集将按照create_time
字段的值进行降序排列。
- 分页操作:
可以通过在查询API中指定from和size参数来实现分页操作,示例代码如下:
SearchRequest searchRequest = new SearchRequest("my_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(0); // 分页起始位置
searchSourceBuilder.size(10); // 每页显示数量
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);
上述代码中,在查询API中指定了from和size参数,以0为起始位置,每页显示10条数据,这样查询出来的结果集将只包含10条数据。
1.4 高亮显示
可以使用查询API和高亮显示API来实现查询结果的高亮显示。
- 高亮显示操作:
可以通过在查询API中指定highlight参数来对查询结果进行高亮显示,示例代码如下:
SearchRequest searchRequest = new SearchRequest("my_index");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title", "keyword"));
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT);
上述代码中,我们在查询API中指定了highlight参数,以title
字段进行高亮显示,并指定了前缀和后缀。这样查询出来的结果集将包含title
字段的高亮显示内容。
- 获取高亮显示结果:
查询出来的结果集中包含了高亮显示的内容,可以通过以下代码获取高亮显示结果:
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField highlight = highlightFields.get("title");
String title = highlight.getFragments()[0].string();
System.out.println(title);
}
上述代码中,我们获取了每个结果集中title
字段的高亮显示结果,并输出到控制台中。文章来源:https://www.toymoban.com/news/detail-426782.html
注意:高亮显示的结果是以片段(fragment)的形式返回的,需要通过调用fragment的
string()
方法获取具体的内容。文章来源地址https://www.toymoban.com/news/detail-426782.html
到了这里,关于Elasticsearch的DSL和在RestClient中的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!