要使用查詢摘要與高亮功能,您需要在創建多元索引時為Text類型的字段開啟摘要與高亮(Highlight)功能,然后在查詢數據時通過設置高亮參數,返回命中查詢詞的片段信息并對查詢詞進行高亮顯示。
場景
查詢摘要與高亮功能可用于全文檢索場景中抽取命中查詢詞附近的片段并高亮命中的查詢詞,適用于網頁搜索、聊天記錄檢索、文檔搜索等場景。
功能概述
查詢摘要與高亮功能可用于在搜索結果中對與查詢詞匹配或相關的文本進行高亮顯示,幫助用戶快速識別到所需的相關查詢內容,提高信息檢索的效率。對于包含嵌套類型的復雜數據結構(例如JSON)也支持使用查詢摘要與高亮功能來精準定位所需信息。表格存儲默認使用<em></em>
標簽來標記匹配的查詢詞。
要使用查詢摘要與高亮功能,您需要完成如下配置:
在創建多元索引時,設置Text類型字段的enableHighlighting參數為True。具體操作,請參見創建多元索引。
重要只支持為Text類型字段開啟查詢摘要與高亮功能。
在數據查詢中使用查詢摘要與高亮功能時,通過指定高亮分片的編碼方式、返回高亮分片的最大數量、前置Tag、后置Tag等參數來自定義高亮顯示的樣式。
假設創建多元索引時已為某個Text類型字段開啟查詢摘要與高亮功能,當該Text類型字段的值為查詢高亮測試
時,在通過MatchPhrase功能查詢關鍵詞高亮
,并指定高亮參數后,可返回高亮片段查詢<em>高亮</em>測試
。
注意事項
在MatchQuery和MatchPhraseQuery中使用查詢摘要與高亮功能時,查詢詞可能會被多個preTag、postTag高亮顯示。
如果Text字段的分詞類型為最大語義分詞,則使用MatchPhraseQuery功能進行數據查詢時不支持使用查詢摘要與高亮功能。
分片切分可能會將文本中的查詢詞分割,此時該查詢詞可能不會被高亮。
接口
查詢摘要與高亮功能的接口為Search,具體的Query類型支持TermQuery、TermsQuery、MatchQuery、MatchPhraseQuery、PrefixQuery、WildcardQuery和NestedQuery。
參數
使用查詢摘要與高亮功能時,一般情況下通過Highlight參數設置高亮參數。對于嵌套類型的子列,則需要通過InnerHits參數設置高亮參數。
Highlight參數
參數 | 說明 | |
highlightEncoder | 對高亮分片原文內容的編碼方式。取值范圍如下:
| |
fieldHighlightParams | 字段高亮參數,僅支持設置SearchQuery中包含關鍵詞查詢的字段。 | |
HighlightParameter | numberOfFragments | 返回高亮分片的最大數量,推薦設置為1。 |
fragmentSize | 每個分片的長度。默認值100。 重要 實際返回分片的長度不會與該值嚴格相等。 | |
preTag | 查詢詞高亮的前置Tag,例如 | |
postTag | 查詢詞高亮的后置Tag,例如 | |
highlightFragmentOrder | 當高亮字段返回多個分片時,分片的排序規則。
|
InnerHits參數
參數 | 說明 |
sort | Nested子行返回時的排序規則。 |
offset | 當Nested列包含多個子行時,子行返回的起始位置。 |
limit | 當Nested列包含多個子行時,返回子行的數量。默認值為3。 |
highlight | Nested子列高亮參數配置。具體配置說明請參見Highlight參數。 |
使用方式
只支持通過SDK方式使用查詢摘要與高亮功能。
進行高亮查詢之前,您需要完成如下準備工作。
使用阿里云賬號或者具有表格存儲操作權限的RAM用戶進行操作。如果需要為RAM用戶授權表格存儲操作權限,請參見通過RAM Policy為RAM用戶授權進行配置。
使用SDK方式進行操作時,如果當前無可用AccessKey,則需要為阿里云賬號或者RAM用戶創建AccessKey。具體操作,請參見創建AccessKey。
已創建數據表。具體操作,請參見數據表操作。
已為數據表創建多元索引且為指定字段開啟了高亮查詢功能。具體操作,請參見創建多元索引。
使用SDK方式進行操作時,還需要完成初始化Client。具體操作,請參見初始化OTSClient。
您可以通過Java SDK、Go SDK、Python SDK和Node.js SDK使用查詢摘要與高亮功能。此處以Java SDK為例介紹查詢摘要與高亮功能的使用。
查詢非嵌套類型字段時使用查詢摘要與高亮
以下示例用于使用MatchQuery功能查詢表中Col_Text列的值能夠匹配hangzhou shanghai
的數據,并在返回結果中對查詢詞進行高亮顯示。其中Col_Text列為Text類型。
/**
* MatchQuery查詢摘要與高亮。
*/
public static void matchQueryWithHighlighting(SyncClient client) {
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName("<TABLE_NAME>")
.indexName("<SEARCH_INDEX_NAME>")
.returnAllColumnsFromIndex(true)
.searchQuery(SearchQuery.newBuilder()
.limit(5)
.query(QueryBuilders.bool()
.should(QueryBuilders.match("Col_Text", "hangzhou shanghai")))
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Text", HighlightParameter.newBuilder()
.highlightFragmentOrder(HighlightFragmentOrder.TEXT_SEQUENCE)
.preTag("<b>")
.postTag("</b>")
.build())
.build())
.build())
.build();
SearchResponse resp = client.search(searchRequest);
// 打印查詢和高亮結果。查詢非嵌套類型字段時設置prefix為空即可。
printSearchHit(resp.getSearchHits(), "");
}
/**
* 打印searchHit內容。
* @param searchHits searchHits
* @param prefix Nested結構輸出時,增加前綴以打印層次信息。
*/
private static void printSearchHit(List<SearchHit> searchHits, String prefix) {
for (SearchHit searchHit : searchHits) {
if (searchHit.getScore() != null) {
System.out.printf("%s Score: %s\n", prefix, searchHit.getScore());
}
if (searchHit.getOffset() != null) {
System.out.printf("%s Offset: %s\n", prefix, searchHit.getOffset());
}
if (searchHit.getRow() != null) {
System.out.printf("%s Row: %s\n", prefix, searchHit.getRow().toString());
}
// 打印各字段高亮分片結果。
if (searchHit.getHighlightResultItem() != null) {
System.out.printf("%s Highlight: \n", prefix);
StringBuilder strBuilder = new StringBuilder();
for (Map.Entry<String, HighlightField> entry : searchHit.getHighlightResultItem().getHighlightFields().entrySet()) {
strBuilder.append(entry.getKey()).append(":").append("[");
strBuilder.append(StringUtils.join(",", entry.getValue().getFragments())).append("]\n");
}
System.out.printf("%s %s", prefix, strBuilder);
}
System.out.println();
}
}
查詢嵌套類型字段時使用查詢摘要與高亮
以下示例用于使用NestedQuery功能查詢表中Col_Nested嵌套類型字段中Level1_Col1_Nested子列的值能夠匹配hangzhou shanghai
的數據,并在返回結果中對查詢詞進行高亮顯示。
/**
* NestedQuery查詢摘要與高亮,通過innerHits設置參數。
*/
public static void nestedQueryWithHighlighting(SyncClient client) {
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName("<TABLE_NAME>")
.indexName("<SEARCH_INDEX_NAME>")
.returnAllColumnsFromIndex(true)
.searchQuery(SearchQuery.newBuilder()
.limit(5)
.query(QueryBuilders.nested()
.path("Col_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.match("Col_Nested.Level1_Col1_Nested", "hangzhou shanghai"))
.innerHits(InnerHits.newBuilder()
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col1_Nested", HighlightParameter.newBuilder().build())
.build())
.build()))
.build())
.build();
SearchResponse resp = client.search(searchRequest);
// 打印高亮結果。
printSearchHit(resp.getSearchHits(), "");
}
/**
* 打印searchHit內容。
* @param searchHits searchHits
* @param prefix Nested結構輸出時,增加前綴以打印層次信息。
*/
private static void printSearchHit(List<SearchHit> searchHits, String prefix) {
for (SearchHit searchHit : searchHits) {
if (searchHit.getScore() != null) {
System.out.printf("%s Score: %s\n", prefix, searchHit.getScore());
}
if (searchHit.getOffset() != null) {
System.out.printf("%s Offset: %s\n", prefix, searchHit.getOffset());
}
if (searchHit.getRow() != null) {
System.out.printf("%s Row: %s\n", prefix, searchHit.getRow().toString());
}
// 打印各字段高亮分片結果。
if (searchHit.getHighlightResultItem() != null) {
System.out.printf("%s Highlight: \n", prefix);
StringBuilder strBuilder = new StringBuilder();
for (Map.Entry<String, HighlightField> entry : searchHit.getHighlightResultItem().getHighlightFields().entrySet()) {
strBuilder.append(entry.getKey()).append(":").append("[");
strBuilder.append(StringUtils.join(",", entry.getValue().getFragments())).append("]\n");
}
System.out.printf("%s %s", prefix, strBuilder);
}
// 嵌套類型高亮結果。
for (SearchInnerHit searchInnerHit : searchHit.getSearchInnerHits().values()) {
System.out.printf("%s Path: %s\n", prefix, searchInnerHit.getPath());
System.out.printf("%s InnerHit: \n", prefix);
printSearchHit(searchInnerHit.getSubSearchHits(), prefix + " ");
}
System.out.println();
}
}
假設多層級嵌套類型字段Col_Nested中包括Level1_Col1_Text(Text類型)和Level1_Col2_Nested(Nested類型)兩列,其中Level1_Col2_Nested嵌套類型字段包括Level2_Col1_Text子列。
以下示例用于通過在NestedQuery中添加BoolQuery對Col_Nested字段中的Level1_Col1_Text子列和Level1_Col2_Nested下的Level2_Col1_Text子列同時使用查詢摘要與高亮功能。
public static void nestedQueryWithHighlighting(SyncClient client) {
SearchRequest searchRequest = SearchRequest.newBuilder()
.tableName("<TABLE_NAME>")
.indexName("<SEARCH_INDEX_NAME>")
.returnAllColumnsFromIndex(true)
.searchQuery(SearchQuery.newBuilder()
.limit(5)
.query(QueryBuilders.nested()
.path("Col_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.bool()
.should(QueryBuilders.match("Col_Nested.Level1_Col1_Text", "hangzhou shanghai"))
.should(QueryBuilders.nested()
.path("Col_Nested.Level1_Col2_Nested")
.scoreMode(ScoreMode.Min)
.query(QueryBuilders.match("Col_Nested.Level1_Col2_Nested.Level2_Col1_Text", "hangzhou shanghai"))
.innerHits(InnerHits.newBuilder()
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col2_Nested.Level2_Col1_Text", HighlightParameter.newBuilder().build())
.build())
.build())))
.innerHits(InnerHits.newBuilder()
.sort(new Sort(Arrays.asList(
new ScoreSort(),
new DocSort()
)))
.highlight(Highlight.newBuilder()
.addFieldHighlightParam("Col_Nested.Level1_Col1_Text", HighlightParameter.newBuilder().build())
.build())
.build()))
.build())
.build();
SearchResponse resp = client.search(searchRequest);
// 打印高亮結果。
printSearchHit(resp.getSearchHits(), "");
}
/**
* 打印searchHit內容。
* @param searchHits searchHits
* @param prefix Nested結構輸出時,增加前綴以打印層次信息。
*/
private static void printSearchHit(List<SearchHit> searchHits, String prefix) {
for (SearchHit searchHit : searchHits) {
if (searchHit.getScore() != null) {
System.out.printf("%s Score: %s\n", prefix, searchHit.getScore());
}
if (searchHit.getOffset() != null) {
System.out.printf("%s Offset: %s\n", prefix, searchHit.getOffset());
}
if (searchHit.getRow() != null) {
System.out.printf("%s Row: %s\n", prefix, searchHit.getRow().toString());
}
// 打印各字段高亮分片結果。
if (searchHit.getHighlightResultItem() != null) {
System.out.printf("%s Highlight: \n", prefix);
StringBuilder strBuilder = new StringBuilder();
for (Map.Entry<String, HighlightField> entry : searchHit.getHighlightResultItem().getHighlightFields().entrySet()) {
strBuilder.append(entry.getKey()).append(":").append("[");
strBuilder.append(StringUtils.join(",", entry.getValue().getFragments())).append("]\n");
}
System.out.printf("%s %s", prefix, strBuilder);
}
// 嵌套類型高亮結果。
for (SearchInnerHit searchInnerHit : searchHit.getSearchInnerHits().values()) {
System.out.printf("%s Path: %s\n", prefix, searchInnerHit.getPath());
System.out.printf("%s InnerHit: \n", prefix);
printSearchHit(searchInnerHit.getSubSearchHits(), prefix + " ");
}
System.out.println();
}
}
計費說明
在數據查詢時使用查詢摘要與高亮功能不影響現有計費規則。
使用VCU模式(原預留模式)時,使用多元索引查詢數據會消耗VCU的計算資源。使用CU模式(原按量模式)時,使用多元索引查詢數據會消耗讀吞吐量。更多信息,請參見多元索引計量計費。
常見問題
相關文檔
多元索引查詢類型包括精確查詢、多詞精確查詢、全匹配查詢、匹配查詢、短語匹配查詢、范圍查詢、前綴查詢、后綴查詢、通配符查詢、基于分詞的通配符查詢、多條件組合查詢、地理位置查詢、嵌套類型查詢、向量檢索、和列存在性查詢,您可以選擇合適的查詢類型進行多維度數據查詢。
如果要對結果集進行排序或者翻頁,您可以使用排序和翻頁功能來實現。具體操作,請參見排序和翻頁。
如果要按照某一列對結果集做折疊,使對應類型的數據在結果展示中只出現一次,您可以使用折疊(去重)功能來實現。具體操作,請參見折疊(去重)。
如果要進行數據分析,例如求最值、求和、統計行數等,您可以使用 Search 接口的統計聚合功能或者 SQL 查詢來實現。具體操作,請參見統計聚合和SQL查詢。
如果要快速導出數據,而不關心整個結果集的順序時,您可以使用 ParallelScan 接口和 ComputeSplits 接口實現多并發導出數據。具體操作,請參見并發導出數據。