具有特殊字元的部分字詞搜尋和模式(連字元、通配符、regex、模式)
部分字詞搜尋是指由字詞片段組成的查詢,其中,您可能只有字詞的開頭、中間或結尾(有時稱為前置詞、infix 或後置詞查詢)。 部分字詞搜尋可能包含片段的組合,通常具有特殊字元,例如連字元、破折號或斜線,屬於查詢字串的一部分。 常見的使用案例包括電話號碼、URL、代碼或連字元複合字的部分。
如果索引沒有代表您要搜尋之文字片段的標記,部分字詞和特殊字元可能會有問題。 在 索引編製的語彙分析階段 (假設預設標準分析器),會捨棄特殊字元、分割複合字,並刪除空格符。 如果您要搜尋在語彙分析期間修改的文字片段,查詢會失敗,因為找不到相符專案。 請考慮此範例:例如 +1 (425) 703-6214
(tokenized as"1"
、 "425"
、 "703"
"6214"
、 ) 的電話號碼不會顯示在查詢中"3-62"
,因為該內容實際上不存在於索引中。
解決方案是在編製索引期間叫用分析器,以保留完整的字串,包括空格和特殊字元,以便您可以在查詢字串中包含空格和字元。 具有完整且未定義的字串可針對「開頭」或「結尾」查詢進行模式比對,您可以在其中根據語彙分析未轉換的字詞來評估您提供的模式。
如果您需要支援呼叫分析和非分析內容的搜尋案例,請考慮在索引中建立兩個字段,針對每個案例建立一個字段。 一個字段會經歷語彙分析。 第二個字段會使用內容保留分析器來儲存完整字串,以發出全字串標記以進行模式比對。
關於部分字詞搜尋
Azure AI 搜尋會在索引中掃描整個標記化字詞,除非您包含通配符佔位元運算元 (*
和 ?
), 或將查詢格式化為正則表達式,否則在部分字詞上找不到相符專案。
部分詞彙是使用這些技術來指定:
正則表達式查詢 可以是 Apache Lucene 下有效的任何正則表示式。
具有前置詞比 對的通配符運算符是指包含字詞開頭的一般辨識模式,後面接著
*
或?
後綴運算符,例如search=cap*
比對 “Cap'n Jack's Waterfront Inn” 或 “Gacc Capital”。 簡單且完整的 Lucene 查詢語法都支援前置詞比對。具有 infix 和後綴的通配符會將 和
?
運算符放在*
字詞的開頭或開頭,而且需要正則表達式語法(其中運算式以正斜線括住)。 例如,查詢字串 (search=/.*numeric.*/
) 會傳回 「英數位元」 和 「英數位元」 的結果作為後綴和 infix 相符專案。
對於正則表達式、通配符和模糊搜尋,分析器不會在查詢時間使用。 針對這些查詢形式,剖析器會透過運算符和分隔符的存在來偵測,查詢字串會傳遞至引擎,而不需要語彙分析。 針對這些查詢表單,會忽略字段上指定的分析器。
注意
當部分查詢字串包含字元時,例如 URL 片段中的斜線,您可能需要新增逸出字元。 在 JSON 中,正斜線 /
會以向後斜線 \
逸出。 因此, search=/.*microsoft.com\/azure\/.*/
是URL片段 microsoft.com/azure/“ 的語法。
解決部分/模式搜尋問題
當您需要搜尋片段或模式或特殊字元時,您可以使用以更簡單的令牌化規則運作的自定義分析器來覆寫預設分析器,以保留索引中的整個字串。
方法看起來像這樣:
- 定義第二個字位來儲存完整版本的字串(假設您想要在查詢時間分析和非分析的文字)
- 評估並選擇在適當粒度層級發出令牌的各種分析器
- 將分析器指派給欄位
- 建置及測試索引
1 - 建立專用欄位
分析器會決定字詞在索引中的標記化方式。 由於分析器會根據每個欄位指派,因此您可以在索引中建立欄位,以針對不同的案例進行優化。 例如,您可以定義 「featureCode」 和 「featureCodeRegex」,以支援第一次的一般全文搜索,並在第二個上定義進階模式比對。 指派給每個欄位的分析器會決定如何在索引中標記每個欄位的內容。
{
"name": "featureCode",
"type": "Edm.String",
"retrievable": true,
"searchable": true,
"analyzer": null
},
{
"name": "featureCodeRegex",
"type": "Edm.String",
"retrievable": true,
"searchable": true,
"analyzer": "my_custom_analyzer"
},
2 - 設定分析器
選擇產生完整字彙令牌的分析器時,下列分析器是常見的選擇:
分析器 | 行為 |
---|---|
語言分析器 | 以複合字或字串、元音突變和動詞形式保留連字元。 如果查詢模式包含破折號,則使用語言分析器可能就已足夠。 |
keyword | 整個欄位的內容會標示為單一字詞。 |
空白 | 只在空格符上分隔。 包含虛線或其他字元的字詞會被視為單一標記。 |
自定義分析器 | (建議)建立自定義分析器可讓您同時指定Tokenizer和Token篩選。 先前的分析器必須依原樣使用。 自定義分析器可讓您挑選要使用的令牌化程式和令牌篩選器。 建議的組合是具有小寫令牌篩選的關鍵詞 Tokenizer。 內建 關鍵詞分析器 本身不會小寫任何大寫文字,這可能會導致查詢失敗。 自定義分析器提供一個機制來新增小寫令牌篩選條件。 |
使用 REST 用戶端,您可以新增 Test Analyzer REST 呼叫 來檢查令牌化輸出。
索引必須存在於搜尋服務上,但可以是空的。 假設現有的索引和包含虛線或部分字詞的欄位,您可以針對特定字詞嘗試各種分析器,以查看發出哪些令牌。
首先,請檢查標準分析器,以瞭解條款預設如何標記化。
{ "text": "SVP10-NOR-00", "analyzer": "standard" }
評估回應以查看如何在索引內標記文字。 請注意每個字詞大小寫、移除連字元,以及子字串如何分成個別標記。 只有符合這些令牌的查詢才會在結果中傳回這份檔。 包含 「10-NOR」 的查詢將會失敗。
{ "tokens": [ { "token": "svp10", "startOffset": 0, "endOffset": 5, "position": 0 }, { "token": "nor", "startOffset": 6, "endOffset": 9, "position": 1 }, { "token": "00", "startOffset": 10, "endOffset": 12, "position": 2 } ] }
現在修改要求以使用
whitespace
或keyword
分析器:{ "text": "SVP10-NOR-00", "analyzer": "keyword" }
這次,回應是由單一令牌所組成,大寫,虛線會保留為字元串的一部分。 如果您需要搜尋模式或部分字詞,例如 「10-NOR」,查詢引擎現在有尋找相符項目的基礎。
{ "tokens": [ { "token": "SVP10-NOR-00", "startOffset": 0, "endOffset": 12, "position": 0 } ] }
重要
請注意,在建置查詢樹狀結構時,查詢剖析器通常會在搜尋表達式中小寫字詞。 如果您在編製索引期間使用不小寫文字輸入的分析器,而且未取得預期的結果,這可能是原因。 解決方案是新增小寫令牌篩選器,如下方的一節所述。
3 - 設定分析器
無論您是評估分析器還是繼續進行特定設定,都必須在欄位定義上指定分析器,而且如果您未使用內建分析器,則可能需要設定分析器本身。 交換分析器時,您通常需要重建索引(卸除、重新建立和重載)。
使用內建分析器
內建分析器可以在欄位定義的屬性上 analyzer
以名稱指定,索引中不需要額外的設定。 下列範例示範如何在欄位上設定 whitespace
分析器。
如需其他案例,以及深入瞭解其他內建分析器,請參閱 內建分析器。
{
"name": "phoneNumber",
"type": "Edm.String",
"key": false,
"retrievable": true,
"searchable": true,
"analyzer": "whitespace"
}
使用自定義分析器
如果您使用 自定義分析器,請使用使用者定義的令牌化程式、令牌篩選器組合,以及可能的組態設定,在索引中定義它。 接下來,在欄位定義上參考它,就像是內建分析器一樣。
當目標為完整令牌化時,建議使用由關鍵詞 Tokenizer 和小寫令牌篩選所組成的自定義分析器。
- 關鍵詞 Tokenizer 會為字段的整個內容建立單一令牌。
- 小寫標記篩選會將大寫字母轉換成小寫文字。 查詢剖析器通常會小寫任何大寫的文字輸入。 小大小寫會使用標記化字詞將輸入同質化。
下列範例說明提供關鍵詞Tokenizer和小寫令牌篩選的自定義分析器。
{
"fields": [
{
"name": "accountNumber",
"analyzer":"myCustomAnalyzer",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false
}
],
"analyzers": [
{
"@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"name":"myCustomAnalyzer",
"charFilters":[],
"tokenizer":"keyword_v2",
"tokenFilters":["lowercase"]
}
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": []
}
注意
keyword_v2
系統會知道 Tokenizer 和 lowercase
Token 篩選條件,並使用其預設組態,這就是為什麼您可以依名稱參考它們,而不需要先定義它們。
4 - 建置和測試
一旦您使用支援案例的分析器和字段定義來定義索引之後,請載入具有代表性字串的檔,以便測試部分字串查詢。
使用 REST 用戶端來查詢本文所述的部分詞彙和特殊字元。
前幾節說明邏輯。 本節會逐步執行測試解決方案時應呼叫的每個 API。
刪除索引 會移除相同名稱的現有索引,以便重新建立索引。
建立索引 會在您的搜尋服務上建立索引結構,包括分析器定義和具有分析器規格的欄位。
載入與 索引具有相同結構的檔,以及可搜尋的內容。 在此步驟之後,您的索引已準備好進行查詢或測試。
測試分析器是在設定分析器中引進的。 使用各種分析器測試索引中的一些字串,以瞭解詞彙的令牌化方式。
搜尋文件說明如何使用簡單語法或通配符和正則表達式的完整 Lucene 語法來建構查詢要求。
對於部分詞彙查詢,例如查詢 「3-6214」 來尋找 「+1(425) 703-6214」 的相符專案,您可以使用簡單的語法:
search=3-6214&queryType=simple
。對於 infix 和後置詞查詢,例如查詢 「num」 或 “numeric 來尋找 ”alphanumeric“ 的相符專案,請使用完整的 Lucene 語法和正則表達式:
search=/.*num.*/&queryType=full
調整查詢效能
如果您實作包含keyword_v2 Tokenizer 和小寫令牌篩選的建議組態,您可能會注意到查詢效能會因為索引中現有令牌的額外令牌篩選處理而降低。
下列範例會新增 EdgeNGramTokenFilter ,讓前置詞比對更快。 令牌會在包含字元的 2-25 個字元組合中產生。 以下是從兩個到七個令牌的範例進展:MS、MSF、MSFT、MSFT/、MSFT/S、MSFT/SQ、MSFT/SQL。
額外的標記化會導致較大的索引。 如果您有足夠的容量來容納較大的索引,此方法的回應時間可能最快速。
{
"fields": [
{
"name": "accountNumber",
"analyzer":"myCustomAnalyzer",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false
}
],
"analyzers": [
{
"@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"name":"myCustomAnalyzer",
"charFilters":[],
"tokenizer":"keyword_v2",
"tokenFilters":["lowercase", "my_edgeNGram"]
}
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": [
{
"@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
"name":"my_edgeNGram",
"minGram": 2,
"maxGram": 25,
"side": "front"
}
]
}
下一步
本文說明分析器如何參與查詢問題和解決查詢問題。 在下一個步驟中,進一步瞭解分析器會影響索引編製和查詢處理。