在 Easysearch Java SDK 2.0.x 使用指南(一) 中,我們介紹了 Easysearch Java SDK 2.0.2 的基本使用和批量操作功能。
在 Easysearch Java SDK 2.0.x 使用指南(二) 中,則詳細介紹了索引管理相關的功能,包括索引的創建、刪除、開關、刷新、滾動等操作,以及新版 SDK 提供的同步和異步兩種調用方式。
本篇文章將繼續向大家介紹 Easysearch Java SDK 2.0.2 的 Query 的使用。
1. QueryString:靈活的全文檢索
QueryString 查詢允許開發者以類似 Easysearch Query DSL 的語法執行全文檢索,非常適合處理用户輸入的複雜搜索條件。
基本概念
fields:指定要檢索的字段列表。query:查詢字符串,支持布爾操作符(如 AND、OR、NOT)。default_operator:當查詢字符串中未明確操作符時使用的默認邏輯操作符。analyze_wildcard:是否對通配符查詢進行分析。
代碼示例
以下示例展示瞭如何通過新版 Java 客户端構建一個 QueryString 查詢,用於檢索標題和內容中同時包含 easysearch 和 java 的文檔:
@Test
public void testQueryString() {
// 定義 JSON 查詢字符串
String jsonQuery = "{\n" +
" \"query_string\": {\n" +
" \"fields\": [\"title\", \"content\"],\n" +
" \"query\": \"easysearch AND java\",\n" +
" \"default_operator\": \"AND\",\n" +
" \"analyze_wildcard\": true\n" +
" }\n" +
"}";
// 使用 JacksonJsonpMapper 解析 JSON 字符串
JacksonJsonpMapper mapper = new JacksonJsonpMapper();
JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery));
Query query = Query._DESERIALIZER.deserialize(parser, mapper);
// 提取 QueryStringQuery 並構建最終查詢
QueryStringQuery queryStringQuery = query.queryString();
Query finalQuery = Query.of(q -> q.queryString(queryStringQuery));
// 輸出最終查詢對象
System.out.println(finalQuery);
}
代碼解析
- 構建 JSON 查詢字符串:定義了
query_string查詢的核心參數,包括字段列表和查詢條件。 - 解析 JSON:使用
JacksonJsonpMapper將 JSON 字符串解析為 Java 對象。 - 提取 QueryStringQuery:從解析後的
Query對象中獲取QueryStringQuery。 - 封裝最終查詢:通過
Query.of方法將QueryStringQuery封裝為最終的Query對象。
使用場景
- 用户輸入的搜索條件需要支持布爾邏輯。
- 需要在多個字段中進行全文檢索。
- 支持模糊搜索(如通配符)的場景。
2. Bool Query:構建複雜的多條件查詢
Bool Query 可以將多個查詢子句組合成一個高級查詢。這些子句通過布爾邏輯組合在一起,用於查找結果中返回的匹配文檔。
Bool Query 的核心子句
| 子句 | 行為 |
|---|---|
must |
邏輯"與"運算符。結果必須匹配此子句中的所有查詢。 |
must_not |
邏輯"非"運算符。所有匹配此子句中查詢的文檔都會從結果中排除。 |
should |
邏輯"或"運算符。結果必須匹配至少一個查詢。匹配的 should 子句越多,文檔的相關性得分越高。你可以使用 minimum_should_match 參數設置必須匹配的最小查詢數量。如果查詢包含 must 或 filter 子句,則 minimum_should_match 的默認值為 0。否則,minimum_should_match 的默認值為 1。 |
filter |
邏輯"與"運算符,在應用其他查詢之前首先應用,以減少數據集。filter 子句中的查詢是一個是或否選項。如果文檔匹配查詢,則會將其返回到結果中;否則不會返回。filter 查詢的結果通常會被緩存,以實現更快的返回。使用 filter 查詢可根據精確匹配、範圍、日期或數字來過濾結果。 |
基於 JSON 的代碼示例
以下代碼展示瞭如何通過 JSON 字符串構建一個複雜的 BoolQuery:
@Test
public void testBoolQueryString() {
// 定義 JSON 查詢字符串
String jsonQuery = "{\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" { \"match\": { \"title\": \"easysearch\" } },\n" +
" { \"match\": { \"content\": \"java programming\" } }\n" +
" ],\n" +
" \"should\": [\n" +
" { \"term\": { \"category\": \"technology\" } },\n" +
" { \"term\": { \"category\": \"programming\" } }\n" +
" ],\n" +
" \"must_not\": [\n" +
" { \"term\": { \"status\": \"draft\" } },\n" +
" { \"range\": { \"publish_date\": { \"lt\": \"2020-01-01\" } } }\n" +
" ],\n" +
" \"filter\": [\n" +
" { \"range\": { \"rating\": { \"gte\": 4 } } },\n" +
" { \"terms\": { \"tags\": [\"search\", \"database\"] } }\n" +
" ],\n" +
" \"minimum_should_match\": 1\n" +
" }\n" +
"}";
// 解析 JSON 並構建查詢
JacksonJsonpMapper mapper = new JacksonJsonpMapper();
JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery));
Query query = Query._DESERIALIZER.deserialize(parser, mapper);
// 提取 BoolQuery 並構建最終查詢
BoolQuery boolQuery = query.bool();
Query finalQuery = Query.of(q -> q.bool(boolQuery));
// 輸出最終查詢對象
System.out.println(finalQuery);
}
使用 Builder 模式構建 BoolQuery
新版 Java 客户端還提供了類型安全的 Builder 模式,簡化了複雜查詢的構建過程:
@Test
public void testBooleanQuery() throws IOException {
// 構建 BoolQuery
BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();
// 添加 must 子句
boolQueryBuilder.must(new MatchQuery.Builder().field("title").query("easysearch").build()._toQuery());
boolQueryBuilder.must(new MatchQuery.Builder().field("content").query("java programming").build()._toQuery());
// 添加 should 子句
boolQueryBuilder.should(new TermQuery.Builder().field("category").value("technology").build()._toQuery());
boolQueryBuilder.should(new TermQuery.Builder().field("category").value("programming").build()._toQuery());
// 添加 must_not 子句
boolQueryBuilder.mustNot(new TermQuery.Builder().field("status").value("draft").build()._toQuery());
// 添加 filter 子句
boolQueryBuilder.filter(new RangeQuery.Builder().field("rating").gte("4").build()._toQuery());
// 構建查詢
Query query = new Query(boolQueryBuilder.build());
System.out.println(query);
}
使用場景
- 構建複雜的多條件查詢。
- 滿足高級搜索需求,例如結合全文檢索和精確匹配。
- 實現複雜的邏輯,如過濾無關數據、優先特定條件。
3. Constant score query:統一評分的過濾查詢
Constant score 查詢用於包裝一個 filter 查詢,併為所有匹配的文檔分配一個統一的相關性分數。這種查詢方式不考慮詞頻 (TF) 和逆文檔頻率 (IDF),適合那些只關心文檔是否匹配而不關心相關度排序的場景。
基本概念
constant_score 的參數
-
filter- (必需) 您希望運行的過濾查詢。任何返回的文檔都必須匹配此查詢。
- 過濾查詢不計算相關性得分。為了提高性能,Easysearch 會自動緩存常用的過濾查詢。
-
boost- (可選) 用作每個匹配過濾查詢的文檔的常量相關性得分的浮點數。默認為 1.0。
基於 JSON 的代碼示例
@Test
public void testConstantScoreQuery() {
// 定義 JSON 查詢字符串
String jsonQuery = "{\n" +
" \"constant_score\": {\n" +
" \"filter\": {\n" +
" \"term\": { \"status\": \"published\" }\n" +
" },\n" +
" \"boost\": 1.2\n" +
" }\n" +
"}";
// 解析 JSON 並構建查詢
JacksonJsonpMapper mapper = new JacksonJsonpMapper();
JsonParser parser = mapper.jsonProvider().createParser(new StringReader(jsonQuery));
Query query = Query._DESERIALIZER.deserialize(parser, mapper);
// 提取 ConstantScoreQuery 並構建最終查詢
ConstantScoreQuery constantScoreQuery = query.constantScore();
Query finalQuery = Query.of(q -> q.constantScore(constantScoreQuery));
System.out.println(finalQuery);
}
使用 Builder 模式構建 ConstantScoreQuery
@Test
public void testConstantScoreQueryBuilder() {
// 使用 Builder 構建 ConstantScoreQuery
ConstantScoreQuery.Builder constantScoreBuilder = new ConstantScoreQuery.Builder();
// 創建 filter 查詢
TermQuery termQuery = new TermQuery.Builder()
.field("status")
.value("published")
.build();
// 設置 filter 和 boost
constantScoreBuilder
.filter(termQuery._toQuery())
.boost(1.2f);
// 構建最終查詢
Query query = Query.of(q -> q.constantScore(constantScoreBuilder.build()));
System.out.println(query);
}
使用場景
- 精確匹配過濾
- 查找特定狀態的文檔
- 不需要考慮相關度排序
- 性能優化
- 過濾查詢會被緩存
- 不計算相關性分數,查詢更快
- 自定義評分
- 需要給所有匹配文檔統一分數
- 覆蓋默認的相關性評分
- 布爾查詢的組件
- 作為 bool 查詢的一部分
- 用於預過濾或調整特定文檔集的分數
通過使用 Constant score 查詢,我們可以在需要簡單過濾和統一評分的場景中獲得更好的性能和更簡單的實現。這種查詢方式特別適合那些不需要複雜相關性計算的應用場景。
總結
本文介紹了 Easysearch Java SDK 2.0.2 中的三種核心查詢:Query String、Bool Query 和 Constant Score。
Query String 擅長靈活處理用户輸入的全文檢索,支持布爾邏輯和通配符。Bool Query 則通過組合 must、must_not、should 和 filter 等子句,滿足複雜的多條件查詢需求。Constant Score 則專注於高效過濾和統一評分,適用於不需要排序的場景。
想要了解更多?
- 客户端 Maven 地址: https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2
- 更詳細的文檔和示例代碼在 官網 持續更新中,請隨時關注!
大家有啥問題或者建議,也歡迎隨時反饋!
關於 Easysearch
INFINI Easysearch 是一個分佈式的搜索型數據庫,實現非結構化數據檢索、全文檢索、向量檢索、地理位置信息查詢、組合索引查詢、多語種支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同時添加和完善多項企業級功能。Easysearch 助您擁有簡潔、高效、易用的搜索體驗。
官網文檔:https://infinilabs.cn/docs/latest/easysearch
作者:張磊,極限科技(INFINI Labs)搜索引擎研發負責人,對 Elasticsearch 和 Lucene 源碼比較熟悉,目前主要負責公司的 Easysearch 產品的研發以及客户服務工作。