“Java Elasticsearch:查询”的版本间差异
小无编辑摘要 |
|||
(未显示同一用户的14个中间版本) | |||
第1行: | 第1行: | ||
[[category:ElasticSearch | [[category:Java&ElasticSearch]] | ||
== 基本用法 == | == 基本用法 == | ||
第79行: | 第78行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== | ==== 绑定 SearchSourceBuilder 到 SearchRequest ==== | ||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
// 将 SearchSourceBuilder 绑定到 SearchRequest 对象 | // 将 SearchSourceBuilder 绑定到 SearchRequest 对象 | ||
第114行: | 第113行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 完整示例 === | === ==完整示例== === | ||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
// 首先创建 RestClient,后续章节通过RestClient对象进行参数配置。 | // 首先创建 RestClient,后续章节通过RestClient对象进行参数配置。 | ||
第147行: | 第146行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == match全文搜索 == | ||
全文搜索是 Elasticsearch 的核心特性之一,Java Elasticsearch 全文搜索查询主要由 '''MatchQueryBuilder''' 这个构造器配置。 | 全文搜索是 Elasticsearch 的核心特性之一,Java Elasticsearch 全文搜索查询主要由 '''MatchQueryBuilder''' 这个构造器配置。 | ||
=== | === 创建“'''MatchQueryBuilder'''” === | ||
有两种方式: | |||
# 直接实例化 MatchQueryBuilder; | # 直接实例化 MatchQueryBuilder; | ||
# | # 通过 QueryBuilders 工具创建; | ||
参数: | |||
* 参数1:字段名; | |||
* 参数2:匹配关键词; | |||
<syntaxhighlight lang="Java" highlight=""> | |||
// 方式一 | |||
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", "梯子教程"); | MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", "梯子教程"); | ||
// 方式二 | |||
// | |||
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "梯子教程"); | QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "梯子教程"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
第187行: | 第189行: | ||
(参考上一节) | (参考上一节) | ||
== | == match_phrase短语查询 == | ||
Elasticsearch 的 match_phrase 短语查询跟 match | Elasticsearch 的 match_phrase 短语查询跟 match 的区别就是:'''关键词不拆分,作为一个整体进行搜索'''。 | ||
=== | === 创建“'''MatchPhraseQueryBuilder'''” === | ||
有两种方式: | |||
# 直接实例化 MatchPhraseQueryBuilder; | # 直接实例化 MatchPhraseQueryBuilder; | ||
# 通过 QueryBuilders 工具创建; | # 通过 QueryBuilders 工具创建; | ||
参数: | |||
* 参数1:字段名; | |||
* 参数2:匹配关键词; | |||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
// 方式一 | |||
MatchPhraseQueryBuilder matchPhraseQueryBuilder = new MatchPhraseQueryBuilder("title", "Elasticsearch 查询语法"); | |||
// | // 方式二 | ||
QueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("title", "Elasticsearch 查询语法"); | |||
/ | </syntaxhighlight> | ||
=== 创建“SearchRequest” === | |||
(参考上一节) | |||
=== 执行请求 === | === 执行请求 === | ||
(参考上一节) | |||
=== 处理结果 === | === 处理结果 === | ||
(参考上一节) | (参考上一节) | ||
== | == term等值匹配 == | ||
Elasticsearch 的 term 查询,主要用于实现等值匹配,类似 SQL 的 fieldname=value 表达式。 | Elasticsearch 的 term 查询,主要用于实现等值匹配,类似 SQL 的 fieldname=value 表达式。 | ||
=== | === 创建“'''TermQueryBuilder'''” === | ||
有两种方式: | 有两种方式: | ||
# 直接实例化 TermQueryBuilder; | # 直接实例化 TermQueryBuilder; | ||
第242行: | 第233行: | ||
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("order_id", 100); | TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("order_id", 100); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 创建“SearchRequest” === | === 创建“SearchRequest” === | ||
(参考上一节) | |||
=== 执行请求 === | === 执行请求 === | ||
(参考上一节) | |||
=== 处理结果 === | === 处理结果 === | ||
(参考上一节) | (参考上一节) | ||
== | == terms多值匹配 == | ||
Elasticsearch terms 查询,用于实现类似 SQL 的 '''in''' 语句,'''匹配其中一个值即可'''。 | |||
=== 创建“'''TermsQueryBuilder'''” === | |||
有两种方式: | |||
# 直接实例化 TermsQueryBuilder; | |||
# 通过 QueryBuilders 工具创建; | |||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
// 方式一 | |||
TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("order_id", 1,2,3,4,5); | |||
// 方式二 | |||
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("order_id", 1,2,3,4,5); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
类似SQL:order_id in (1,2,3,4,5) | |||
=== 创建“SearchRequest” === | |||
(参考上一节) | |||
=== 执行请求 === | |||
(参考上一节) | |||
=== 处理结果 === | |||
(参考上一节) | |||
== range范围匹配 == | |||
Elasticsearch 的 range 范围匹配,可以实现类似 SQL 语句中的 >, >=, <, <= 关系表达式。 | |||
=== 创建“'''RangeQueryBuilder'''” === | |||
有两种方式: | |||
# 直接实例化 RangeQueryBuilder; | |||
# 通过 QueryBuilders 工具创建; | |||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
// 方式一 | |||
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("price"); | |||
rangeQueryBuilder.gte(100); | |||
rangeQueryBuilder.lte(200); | |||
// 方式二 | |||
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(100).lte(200); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
等价SQL:price > 100 and price < 200 | |||
=== 创建“SearchRequest” === | |||
(参考上一节) | |||
=== 执行请求 === | |||
(参考上一节) | |||
=== 处理结果 === | |||
(参考上一节) | |||
== bool组合查询 == | |||
Elasticsearch bool组合查询,通过 '''must'''(且)和 '''should'''(或)逻辑运算组合 term、terms、range 等 ES 查询子句,实现复杂的查询需求,类似 SQL 的where子句。 | |||
=== 创建“'''BoolQueryBuilder'''” === | |||
bool查询支持多层嵌套,最终组合出复杂的查询条件。 | |||
<syntaxhighlight lang="Java" highlight=""> | <syntaxhighlight lang="Java" highlight=""> | ||
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery() | |||
.must(QueryBuilders.termQuery("shop_id", 100)) // 通过must设置term子查询 | |||
.must(QueryBuilders.termQuery("status", 3)) // 通过must设置term子查询 | |||
.should(QueryBuilders.rangeQuery("price").gte(100).lte(300));// 通过should设置range子查询 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
等价SQL:shop_id=100 and status=3 or (price >= 100 and price <= 300) | |||
=== 创建“SearchRequest” === | |||
(参考上一节) | |||
=== 执行请求 === | |||
(参考上一节) | |||
=== 处理结果 === | |||
(参考上一节) | |||
== geo查询 == | |||
Java Elasticsearch geo查询主要包括: | |||
* 按距离搜索('''GeoDistanceQueryBuilder''') | |||
*: <syntaxhighlight lang="Java" highlight=""> | |||
// 根据location坐标字段和当前位置,搜索1千米范围的数据 | |||
GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location") | |||
.distance("1km") | |||
.point(new GeoPoint(39.889916, 116.379547)); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
* 按距离排序('''GeoDistanceSortBuilder''') | |||
*: <syntaxhighlight lang="Java" highlight=""> | |||
// 构建GeoDistanceSortBuilder设置按距离排序参数 | |||
GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", new GeoPoint(39.889916, 116.379547)); | |||
// 升序排序 | |||
geoDistanceSortBuilder.order(SortOrder.ASC); | |||
/* | |||
* 创建 SearchRequest 对象 | |||
* 创建 SearchSourceBuilder 对象 | |||
* 设置搜索参数 | |||
* !!! 设置排序参数 !!! | |||
* 绑定SearchSourceBuilder到SearchRequest | |||
*/ | |||
... | |||
... | |||
... | |||
builder.sort(geoDistanceSortBuilder); // 设置排序参数 | |||
... | |||
</syntaxhighlight> | </syntaxhighlight> | ||
* 按矩形范围搜索('''GeoBoundingBoxQueryBuilder''') | |||
*: <syntaxhighlight lang="Java" highlight=""> | |||
<syntaxhighlight lang="Java" highlight=""> | // 根据location坐标字段和一个矩形范围,匹配文档 | ||
GeoBoundingBoxQueryBuilder queryBuilder = QueryBuilders.geoBoundingBoxQuery("location") | |||
.setCorners( // 设置矩形坐标 | |||
new GeoPoint(40.73, -74.1), // 设置矩形的左上角坐标 | |||
new GeoPoint(40.717, -73.99) // 设置矩形的右下角坐标 | |||
); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 创建“SearchRequest” === | |||
(参考上一节) | |||
=== 执行请求 === | |||
(参考上一节) | |||
=== 处理结果 === | |||
(参考上一节) | |||
2023年3月31日 (五) 22:03的最新版本
基本用法
实现ES查询的关键步骤:
- 创建 RestHighLevelClient,Java ES Client对象;
- 创建 SearchRequest 对象:负责设置搜索参数;
- 通过 Client对象发送请求;
- 处理搜索结果;
创建“RestHighLevelClient”
略(参考:Java Elasticsearch:基础:连接配置)
创建“SearchRequest”
创建 SearchRequest 对象步骤如下:
- 创建 SearchRequest 对象;
- 通过 SearchSourceBuilder 设置搜索参数;
- 将 SearchSourceBuilder 绑定到 SearchRequest 对象;
- 实际上大部分 SearchRequest 对象的搜索参数都是通过 SearchSourceBuilder 对象间接设置。
初始化“SearchRequest”
SearchRequest 负责设置搜索参数,包括:ES Query、分页参数等等常用设置(通过 SearchSourceBuilder 对象间接设置)。
// 创建SearchRequest对象,索引名=posts
SearchRequest searchRequest = new SearchRequest("posts");
创建“SearchSourceBuilder”
通过 SearchSourceBuilder 间接完成搜索参数的设置。
// 创建SearchSourceBuilder,构建ES搜索
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
构造查询条件
Java ES 查询条件是通过 QueryBuilders 工具类构建的:
QueryBuilder 是所有 Java ES 查询的基础接口;
// 例子-构建一个Match模糊查询
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("user", "kimchy")
.fuzziness(Fuzziness.AUTO)
.prefixLength(3)
.maxExpansions(10);
// 将QueryBuilders构建的查询,绑定到SearchSourceBuilder对象
sourceBuilder.query(matchQueryBuilder);
或:
// 设置ES查询条件
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
设置分页参数
// 设置分页参数,偏移从0开始
sourceBuilder.from(0);
// 设置分页参数,分页大小=5
sourceBuilder.size(5);
设置排序参数
// 根据id字段,升序
sourceBuilder.sort("id", SortOrder.ASC);
设置请求超时时间
// 设置请求超时时间,60秒
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
绑定 SearchSourceBuilder 到 SearchRequest
// 将 SearchSourceBuilder 绑定到 SearchRequest 对象
searchRequest.source(sourceBuilder);
执行请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
处理结果
RestStatus status = searchResponse.status(); // ES请求状态
TimeValue took = searchResponse.getTook(); // 执行时间
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
Boolean timedOut = searchResponse.isTimedOut(); // 是否超时
// 获取hits,SearchHits对象包含搜索结果
SearchHits hits = searchResponse.getHits();
// 搜索结果总数
TotalHits totalHits = hits.getTotalHits();
long numHits = totalHits.value;
// 遍历搜索结果
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 获取文档内容,json字符串格式
String sourceAsString = hit.getSourceAsString();
// 获取文档内容,Map对象格式
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
}
==完整示例==
// 首先创建 RestClient,后续章节通过RestClient对象进行参数配置。
RestClientBuilder restClientBuilder = RestClient.builder(
new HttpHost("localhost", 9200, "http"), // 设置ES服务地址,支持多个
new HttpHost("localhost", 9201, "http"));
// 创建 RestHighLevelClient,请求都是通过 RestHighLevelClient 实例发出去的。
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
// 创建 SearchRequest 对象
SearchRequest searchRequest = new SearchRequest();
// 通过 SearchSourceBuilder 构建搜索参数
SearchSourceBuilder builder = new SearchSourceBuilder();
// 通过 QueryBuilders 构建ES查询条件
builder.query(QueryBuilders.termsQuery("order_id", 1,2,3,4,5));
// 设置搜索参数
searchRequest.source(builder);
// 执行ES请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
// 获取搜索到的文档
SearchHits hits = searchResponse.getHits();
// 遍历搜索结果
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 获取文档内容,json字符串格式
String sourceAsString = hit.getSourceAsString();
// 获取文档内容,Map对象格式
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
}
match全文搜索
全文搜索是 Elasticsearch 的核心特性之一,Java Elasticsearch 全文搜索查询主要由 MatchQueryBuilder 这个构造器配置。
创建“MatchQueryBuilder”
有两种方式:
- 直接实例化 MatchQueryBuilder;
- 通过 QueryBuilders 工具创建;
参数:
- 参数1:字段名;
- 参数2:匹配关键词;
// 方式一
MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", "梯子教程");
// 方式二
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "梯子教程");
创建“SearchRequest”
Java 所有的 ES 查询请求都是通过 SearchRequest 对象进行设置,因此需要实例化 SearchRequest 对象,设置 query 参数。
SearchRequest searchRequest = new SearchRequest();
// 通过SearchSourceBuilder构建搜索参数
SearchSourceBuilder builder = new SearchSourceBuilder();
// 设置query参数,绑定前面创建的Query对象
builder.query(matchQueryBuilder);
// 设置SearchRequest搜索参数
searchRequest.source(builder);
执行请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
处理结果
(参考上一节)
match_phrase短语查询
Elasticsearch 的 match_phrase 短语查询跟 match 的区别就是:关键词不拆分,作为一个整体进行搜索。
创建“MatchPhraseQueryBuilder”
有两种方式:
- 直接实例化 MatchPhraseQueryBuilder;
- 通过 QueryBuilders 工具创建;
参数:
- 参数1:字段名;
- 参数2:匹配关键词;
// 方式一
MatchPhraseQueryBuilder matchPhraseQueryBuilder = new MatchPhraseQueryBuilder("title", "Elasticsearch 查询语法");
// 方式二
QueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("title", "Elasticsearch 查询语法");
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)
term等值匹配
Elasticsearch 的 term 查询,主要用于实现等值匹配,类似 SQL 的 fieldname=value 表达式。
创建“TermQueryBuilder”
有两种方式:
- 直接实例化 TermQueryBuilder;
- 通过 QueryBuilders 工具创建;
// 方式一
TermQueryBuilder termQueryBuilder = new TermQueryBuilder("order_id", 100);
// 方式二
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("order_id", 100);
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)
terms多值匹配
Elasticsearch terms 查询,用于实现类似 SQL 的 in 语句,匹配其中一个值即可。
创建“TermsQueryBuilder”
有两种方式:
- 直接实例化 TermsQueryBuilder;
- 通过 QueryBuilders 工具创建;
// 方式一
TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("order_id", 1,2,3,4,5);
// 方式二
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("order_id", 1,2,3,4,5);
类似SQL:order_id in (1,2,3,4,5)
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)
range范围匹配
Elasticsearch 的 range 范围匹配,可以实现类似 SQL 语句中的 >, >=, <, <= 关系表达式。
创建“RangeQueryBuilder”
有两种方式:
- 直接实例化 RangeQueryBuilder;
- 通过 QueryBuilders 工具创建;
// 方式一
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("price");
rangeQueryBuilder.gte(100);
rangeQueryBuilder.lte(200);
// 方式二
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(100).lte(200);
等价SQL:price > 100 and price < 200
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)
bool组合查询
Elasticsearch bool组合查询,通过 must(且)和 should(或)逻辑运算组合 term、terms、range 等 ES 查询子句,实现复杂的查询需求,类似 SQL 的where子句。
创建“BoolQueryBuilder”
bool查询支持多层嵌套,最终组合出复杂的查询条件。
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("shop_id", 100)) // 通过must设置term子查询
.must(QueryBuilders.termQuery("status", 3)) // 通过must设置term子查询
.should(QueryBuilders.rangeQuery("price").gte(100).lte(300));// 通过should设置range子查询
等价SQL:shop_id=100 and status=3 or (price >= 100 and price <= 300)
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)
geo查询
Java Elasticsearch geo查询主要包括:
- 按距离搜索(GeoDistanceQueryBuilder)
// 根据location坐标字段和当前位置,搜索1千米范围的数据 GeoDistanceQueryBuilder queryBuilder = QueryBuilders.geoDistanceQuery("location") .distance("1km") .point(new GeoPoint(39.889916, 116.379547));
- 按距离排序(GeoDistanceSortBuilder)
// 构建GeoDistanceSortBuilder设置按距离排序参数 GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", new GeoPoint(39.889916, 116.379547)); // 升序排序 geoDistanceSortBuilder.order(SortOrder.ASC); /* * 创建 SearchRequest 对象 * 创建 SearchSourceBuilder 对象 * 设置搜索参数 * !!! 设置排序参数 !!! * 绑定SearchSourceBuilder到SearchRequest */ ... ... ... builder.sort(geoDistanceSortBuilder); // 设置排序参数 ...
- 按矩形范围搜索(GeoBoundingBoxQueryBuilder)
// 根据location坐标字段和一个矩形范围,匹配文档 GeoBoundingBoxQueryBuilder queryBuilder = QueryBuilders.geoBoundingBoxQuery("location") .setCorners( // 设置矩形坐标 new GeoPoint(40.73, -74.1), // 设置矩形的左上角坐标 new GeoPoint(40.717, -73.99) // 设置矩形的右下角坐标 );
创建“SearchRequest”
(参考上一节)
执行请求
(参考上一节)
处理结果
(参考上一节)