很多時候搜尋使用者對查詢語句具有模糊感覺,他們只能提供大約的描述。比如一個語句的部分,或者字句順序顛倒等。通過模糊查詢可以幫助使用者更準確的找出他們希望搜尋的結果。
模糊查詢包括前字尾,語句(phrase)查詢。字首查詢在非文字查詢和全文查詢欄位中使用是有著不同的效果:在非文字欄位查詢中我們需要嚴格按照詞字順序進行匹配,而全文查詢中由於目標欄位在構建索引時已經進行了分詞處理,所以匹配是在分詞中進行匹配的。下面是一些非文字前字尾查詢的例子:
POST /bank/_search
{
"query" : {
"prefix" : {
"address.keyword": "880"
}
}
}
POST /bank/_search
{
"query" : {
"wildcard": {
"address.keyword": "*Holmes*"
}
}
}
POST /bank/_search
{
"query" : {
"regexp": {
"address.keyword": ".*Holmes.*"
}
}
}
elastic4例子:
val qPrefix = search("bank").query(prefixQuery("address.keyword","880"))
val qWildcard = search("bank").query(wildcardQuery("address.keyword","*Holmes*"))
val qRegex = search("bank").query(regexQuery("address.keyword",".*Holmes.*"))
全文查詢中常用match_phrase:這是一種語句查詢。如:
GET /books/_search
{
"query": {
"match_phrase": {
"publisher": "人民出版社"
}
}
}
一個有意義的語句中每個字在句子中的位置都是按順序的。“人民出版社”可能被分詞成“人民”、“人民版”,“人民社”、“社“等。但實際上很多圖書行內人稱“人社版“。也就是說應該容許一定程度的靈活性,即字在句中的位置容許一定程度的錯位。這個程度可以用slop來表示:
GET /books/_search
{
"query": {
"match_phrase": {
"publisher": {
"query": "人社版",
"slop" : 10
}
}
}
}
上面這個slop = 10 的意思是我們可以容許十步字距調整。slop值越大覆蓋詞段越廣,不過可能會影響效率。elastic4請求表達如下:
val qPhrase = search("books").query(
matchPhraseQuery("PUBLISHER","人社版").slop(10)
)
另外,match_phrase在使用者錄入查詢條件時可以作為提示(auto-completion)或者即錄即查(search_as_you_type)使用。這時用字首查詢match_phrase_prefix最為合適。因為可以兼顧英文到字母層級的錄入查詢:
GET /books/_search
{
"query": {
"match_phrase_prefix": {
"publisher": {
"query": "人社版",
"slop" : 10
}
}
}
}
用elastic4來表示:
val qPhrasePfx = search("books").query(
matchPhrasePrefixQuery("PUBLISHER","人社版").slop(10)
)