成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

要搞懂 Elasticsearch Match Query,看這篇就夠了

zhjx922 / 2138人閱讀

摘要:百度百科通過(guò)模糊搜索可以查詢(xún)出存在一定相似度的單詞,那么怎么計(jì)算兩個(gè)單詞是否有相似度以及相似度的大小呢這就要了解下另外一個(gè)概念叫做萊文斯坦距離,是編輯距離的一種。在查詢(xún)或者類(lèi)型的字段時(shí)可以看做是萊文斯坦距離。

引言

昨天是感恩節(jié),上幼兒園的女兒在老師的叮囑下,晚上為我和老婆洗了腳(形式上的^_^),還給我們每人端了一杯水??粗⒆右惶焯斓拈L(zhǎng)大,懂事,感覺(jué)很開(kāi)心,話說(shuō)咱們程序員這么辛苦是為了什么?不就是為了老婆,孩子,熱炕頭,有一個(gè)溫暖幸福的家庭,再捎帶著用代碼改變一下世界嗎?想到這里,頓時(shí)覺(jué)得學(xué)習(xí),創(chuàng)作博客的勁頭也的更足了。哈哈,扯遠(yuǎn)了,書(shū)歸正傳,今天我們來(lái)聊聊 Match Query。

Match Query 是最常用的 Full Text Query 。無(wú)論需要查詢(xún)什么字段, match 查詢(xún)都應(yīng)該會(huì)是首選的查詢(xún)方式。它既能處理全文字段,又能處理精確字段。

構(gòu)建示例

為了能夠在后面能深入理解 Match Query 中的各個(gè)屬性的意義,我們先構(gòu)建一個(gè) index 示例(有興趣的同學(xué)只要將下面字段粘貼到 sense 中就可以創(chuàng)建)。

PUT matchtest
{ 
}

PUT matchtest/_mapping/people
{
  "properties": {
    "age": {
      "type": "integer"
    },
    "hobbies": {
      "type": "text"
    },
    "name": {
      "type": "keyword"
    }
  }
}

PUT matchtest/people/1
{
  "name" : "Jim",
  "age": 10,
  "hobbies": "football, basketball, pingpang"
}


PUT matchtest/people/2
{
  "name" : "Tom",
  "age": 12,
  "hobbies": "swimming, football"
}
match operator 參數(shù)

match 查詢(xún)是一種 bool 類(lèi)型的查詢(xún)。什么意思呢?舉個(gè)例子,查詢(xún) people type 的 hobbies 為 football basketball

GET matchtest/people/_search
{
  "query": {
    "match": {
      "hobbies": "football basketball"
    }
  }
}

會(huì)將上面的兩個(gè)文檔都搜索出來(lái)。為什么?上面的查詢(xún)其實(shí)隱藏了一個(gè)默認(rèn)參數(shù)operator , 它的默認(rèn)值是 or ,也就是說(shuō)上面的查詢(xún)也可以寫(xiě)成這種形式

GET matchtest/people/_search
{
  "query": {
    "match": {
      "hobbies": {
        "query": "football basketball",
        "operator": "or"
      }
    }
  }
}

這樣就比較容易理解了,既然是 or 操作符,就表示只要查詢(xún)的文檔的 hobbies 字段中含有 footballbasketball 任意一個(gè),就可以被匹配到。

如果將 operator 操作符的值改為 and ,則表示需要同時(shí)包含 footballbasketball , 得到的結(jié)果就只能是 文檔 1 Jim 小朋友了。

analyzer

analyzer 屬性是指在對(duì)查詢(xún)文本分析時(shí)的分析器

如果沒(méi)有指定則會(huì)使用字段mapping 時(shí)指定的分析器

如果字段在 mapping 時(shí)也沒(méi)有明顯指定,則會(huì)使用默認(rèn)的 search analyzer。

這里我們也沒(méi)有指定,就會(huì)使用默認(rèn)的,就不舉例了,在后面文章講解 analyzer 時(shí)再拓展。

lenient 參數(shù)

默認(rèn)值是 false , 表示用來(lái)在查詢(xún)時(shí)如果數(shù)據(jù)類(lèi)型不匹配且無(wú)法轉(zhuǎn)換時(shí)會(huì)報(bào)錯(cuò)。如果設(shè)置成 true 會(huì)忽略錯(cuò)誤。

例如, 例子中的 ageinteger 類(lèi)型的,如果查詢(xún) age=xxy ,就會(huì)導(dǎo)致無(wú)法轉(zhuǎn)換而報(bào)錯(cuò)。

GET matchtest/_search
{
  "query": {
    "match": {
      "age" : {
        "query": "xxx"
      }
    }
  }
}

而如果將 lenient 參數(shù)設(shè)置為 true ,就會(huì)忽略這個(gè)錯(cuò)誤

GET matchtest/_search
{
  "query": {
    "match": {
      "age" : {
        "query": "xxx",
        "lenient": true
      }
    }
  }
}

注意,如果將 age 字段的值設(shè)置為字符串 "10", 來(lái)查詢(xún),由于能夠轉(zhuǎn)換成整數(shù),這時(shí) elastic 內(nèi)部會(huì)將 字符串先轉(zhuǎn)換成整數(shù)再做查詢(xún),不會(huì)報(bào)錯(cuò)。

Fuzziness fuzzniess 參數(shù)

fuzziness 參數(shù)可以是查詢(xún)的字段具有模糊搜索的特性。來(lái)先了解下什么是模糊搜索。

什么是模糊搜索?
模糊搜索是指系統(tǒng)允許被搜索信息和搜索提問(wèn)之間存在一定的差異,這種差異就是“模糊”在搜索中的含義。例如,查找名字Smith時(shí),就會(huì)找出與之相似的Smithe, Smythe, Smyth, Smitt等。 

——百度百科

通過(guò)模糊搜索可以查詢(xún)出存在一定相似度的單詞,那么怎么計(jì)算兩個(gè)單詞是否有相似度以及相似度的大小呢?這就要了解下另外一個(gè)概念:Levenshtein Edit Distance

Levenshtein Edit Distance
Levenshtein Edit Distance 叫做萊文斯坦距離**,是編輯距離的一種。指兩個(gè)字串之間,由一個(gè)轉(zhuǎn)成另一個(gè)所需的最少編輯操作次數(shù)。允許的編輯操作包括將一個(gè)字符替換成另一個(gè)字符,插入一個(gè)字符,刪除一個(gè)字符。

例如,單詞 "god" 只需要插入一個(gè) "o" 字符就可以變?yōu)? "good",因此它們之間的編輯距離為 1。

fuzziness 參數(shù)取值規(guī)則

了解了上面兩個(gè)概念,回過(guò)頭再來(lái)看下 fuzziness 參數(shù)。

在查詢(xún) text 或者 keyword 類(lèi)型的字段時(shí), fuzziness 可以看做是萊文斯坦距離。

fuzziness 參數(shù)的取值如下

0,1,2 表示最大可允許的萊文斯坦距離

AUTO

會(huì)根據(jù)詞項(xiàng)的長(zhǎng)度來(lái)產(chǎn)生可編輯距離,它還有兩個(gè)可選參數(shù),形式為AUTO:[low],[high], 分別表示短距離參數(shù)和長(zhǎng)距離參數(shù);如果沒(méi)有指定,默認(rèn)值是 AUTO:3,6 表示的意義如下

0..2

單詞長(zhǎng)度為 0 到 2 之間時(shí)必須要精確匹配,這其實(shí)很好理解,單詞長(zhǎng)度太短是沒(méi)有相似度可言的,例如 "a" 和 "b"。

3..5

單詞長(zhǎng)度 3 到 5 個(gè)字母時(shí),最大編輯距離為 1

>5

單詞長(zhǎng)度大于 5 個(gè)字母時(shí),最大編輯距離為 2

最佳實(shí)踐: fuzziness 在絕大多數(shù)場(chǎng)合都應(yīng)該設(shè)置成 AUTO

如果不設(shè)置 fuziness 參數(shù),查詢(xún)是精確匹配的。

來(lái)看例子,上面創(chuàng)建了一個(gè) doc

PUT matchtest/people/1
{
  "name" : "Jim",
  "age": 10,
  "hobbies": "football, basketball, pingpang"
}

設(shè)置 fuzzinessAUTO ,

其中 hobbies 字段的值 football 長(zhǎng)度 > 5, 此時(shí)我們找一個(gè)編輯距離為 2 的單詞 footba22 來(lái)查詢(xún),應(yīng)該匹配到

其中 name 字段的值 jim 長(zhǎng)度在 3 和 5 之間,此時(shí)找一個(gè)編輯距離為 1 的單詞 jiO 應(yīng)匹配到,而編輯距離為 2 的 jOO 就不應(yīng)匹配到。

來(lái),驗(yàn)證下

GET matchtest/_search
{
  "query": {
    "match": {
      "hobbies": {
        "query": "footba22",
        "fuzziness": "AUTO"
      }
    }
  }
}

GET matchtest/_search
{
  "query": {
    "match": {
      "name": {
        "query": "jiO",
        "fuzziness": "AUTO"
      }
    }
  }
}


GET matchtest/_search
{
  "query": {
    "match": {
      "name": {
        "query": "jOO",
        "fuzziness": "AUTO"
      }
    }
  }
}
prefix_length

prefix_length 表示不能沒(méi)模糊化的初始字符數(shù)。由于大部分的拼寫(xiě)錯(cuò)誤發(fā)生在詞的結(jié)尾,而不是詞的開(kāi)始,使用 prefix_length 就可以完成優(yōu)化。注意 prefix_length 必須結(jié)合 fuzziness 參數(shù)使用。

例如,在查詢(xún) hobbies 中的 football 時(shí),將 prefix_length 參數(shù)設(shè)置為 3,這時(shí) foatball 將不能被匹配。

GET matchtest/_search
{
  "query": {
    "match": {
      "hobbies": {
        "query": "foatball",
        "fuzziness": "AUTO",
        "prefix_length": 3
      }
    }
  }
}

TODO(max_expansions 參數(shù)對(duì)于 match 查詢(xún)而言,沒(méi)理解表示的意義,如果您知道這個(gè)參數(shù)的用法,請(qǐng)給我留言告知,不勝感謝! )

Zero terms Query

先看例子, 先創(chuàng)建一個(gè)文檔 zero_terms_query_test 其中 message 字段使用 stop 分析器,這個(gè)分析器會(huì)將 stop words 停用詞在索引時(shí)全都去掉。

PUT matchtest1

PUT matchtest1/_mapping/zero_terms_query_test
{
  "properties": {
    "message": {
      "type": "text",
      "analyzer": "stop"
    }
  }
}


PUT matchtest1/zero_terms_query_test/1
{
  "message": "to be or not to be"
}

GET matchtest1/_search
{
  "query": {
    "match": {
      "message": {
        "query": "to be or not to be",
        "operator": "and",
        "zero_terms_query": "none"
      }
    }
  }
}

那么就像 message 字段中的 to be or not to be 這個(gè)短語(yǔ)中全部都是停止詞,一過(guò)濾,就什么也沒(méi)有了,得不到任何 tokens, 那搜索時(shí)豈不什么都搜不到。

POST _analyze
{
  "analyzer": "stop",
  "text": "to be or not to be"
}

zero_terms_query 就是為了解決這個(gè)問(wèn)題而生的。它的默認(rèn)值是 none ,就是搜不到停止詞(對(duì) stop 分析器字段而言),如果設(shè)置成 all ,它的效果就和 match_all 類(lèi)似,就可以搜到了。

GET matchtest1/_search
{
  "query": {
    "match": {
      "message": {
        "query": "to be or not to be",
        "operator": "and",
        "zero_terms_query": "all"
      }
    }
  }
}
Cutoff frequency

查詢(xún)字符串時(shí)的詞項(xiàng)會(huì)分成低頻詞(更重要)和高頻詞(次重要)兩類(lèi),像前面所說(shuō)的停用詞 (stop word)就屬于高頻詞,它雖然出現(xiàn)頻率較高,但在匹配時(shí)可能并不太相關(guān)。實(shí)際上,我們往往是想要文檔能盡可能的匹配那些低頻詞,也就是更重要的詞項(xiàng)。

要實(shí)現(xiàn)這個(gè)需求,只要在查詢(xún)時(shí)配置 cutoff_frequency 參數(shù)就可以了。假設(shè)我們將 cutoff_frequency 設(shè)置成 0.01 就表示

任何詞項(xiàng)在文檔中超過(guò) 1%, 被認(rèn)為是高頻詞

其他的詞項(xiàng)會(huì)被認(rèn)為低頻詞

從而將高頻詞(次重要的詞)挪到可選子查詢(xún)中,讓它們只參與評(píng)分,而不參與匹配;高頻詞(更重要的詞)參與匹配和評(píng)分。

這樣一來(lái),就不再需要 stopwords 停用詞文件了,從而變成了動(dòng)態(tài)生成停用詞: 高頻詞就會(huì)被看做是停用詞。這種配置只是對(duì)于詞項(xiàng)比較多的場(chǎng)合如 email body,文章等適用,文字太少, cutoff_frequency 選項(xiàng)設(shè)置的意義就不大了。

cutoff_frequency 配置有兩種形式

指定為一個(gè)分?jǐn)?shù)( 0.01 )表示出現(xiàn)頻率

指定為一個(gè)正整數(shù)( 5 )則表示出現(xiàn)次數(shù)

下面給個(gè)例子, 在創(chuàng)建的 3 個(gè)文檔中都包含 "be " 的單詞,在查詢(xún)時(shí)將 cutoff_frequency 參數(shù)設(shè)置為 2, 表示 "be" 就是高頻詞,只會(huì)參與評(píng)分,但在匹配時(shí)不做考慮。

此時(shí)查詢(xún)的內(nèi)容為 "to be key" ,由于 "be" 詞項(xiàng)是高頻詞,因?yàn)樵谖臋n中必須要存在 "to" 或者 "key" 才能匹配,因此文檔 3 不能匹配。

PUT /matchtest2

PUT matchtest2/_mapping/cutoff_frequency_test
{
  "properties": {
    "message": {
      "type": "text"
    }
  }
}

PUT matchtest2/cutoff_frequency_test/1
{
  "message": "to be or not to be to be or"
}

PUT matchtest2/cutoff_frequency_test/2
{
  "message": "be key or abc"
}

PUT matchtest2/cutoff_frequency_test/3
{
  "message": "or to be or to to be or"
}

GET matchtest2/_search
{
  "query": {
    "match": {
      "message": {
        "query": "to be key",
        "cutoff_frequency": 2
      }
    }
  }
}
synonyms

synonyms 是指同義詞,只要索引和字段中配置了同義詞過(guò)濾器,match 查詢(xún)是支持多詞條的同義詞擴(kuò)展的。在應(yīng)用過(guò)濾器后,解析器會(huì)對(duì)每個(gè)多次條同義詞創(chuàng)建一個(gè)語(yǔ)句查詢(xún)。

例如,同義詞 USA, united states of America 就會(huì)構(gòu)建出 (USA OR ("united states of America"))??聪旅胬樱?/p>

PUT /matchtest4
{
    "settings": {
        "index" : {
            "analysis" : {
                "analyzer" : {
                    "synonym" : {
                        "tokenizer" : "whitespace",
                        "filter" : ["synonym"]
                    }
                },
                "filter" : {
                    "synonym" : {
                        "type" : "synonym",
                        "synonyms" : [
                            "USA, united states of America"
                        ]
                    }
                }
            }
        }
    }
}

PUT /matchtest4/_mapping/synonyms_test
{
  "properties": {
    "message": {
      "type": "text",
      "analyzer": "synonym"
    }
  }
}

PUT /matchtest4/synonyms_test/1
{
  "message": "united states of America people"
}


GET /matchtest4/_search
{
  "query": {
    "match": {
      "message": {
        "query": "USA"
      }
    }
  }
}
小結(jié)

本文以代碼實(shí)例的方式完整的講解了 Match Query 的各種使用場(chǎng)景和參數(shù)意義。下篇會(huì)講解 Match Phrase Query 敬請(qǐng)期待。

參考文檔

[Elasticsearch Query DSL Match Query] (https://www.elastic.co/guide/...

傳送門(mén)

reycg-blog

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72334.html

相關(guān)文章

  • JS正則表達(dá)式入門(mén),看這篇就夠了

    摘要:如果遇到非常的復(fù)雜的匹配,正則表達(dá)式的優(yōu)勢(shì)就更加明顯了。關(guān)于正則表達(dá)式書(shū)寫(xiě)規(guī)則,可查看,上面說(shuō)的很清楚了,我就不貼出來(lái)了。替換與正則表達(dá)式匹配的子串,并返回替換后的字符串。結(jié)語(yǔ)正則表達(dá)式并不難,懂了其中的套路之后,一切都變得簡(jiǎn)單了。 前言 在正文開(kāi)始前,先說(shuō)說(shuō)正則表達(dá)式是什么,為什么要用正則表達(dá)式?正則表達(dá)式在我個(gè)人看來(lái)就是一個(gè)瀏覽器可以識(shí)別的規(guī)則,有了這個(gè)規(guī)則,瀏覽器就可以幫我們判斷...

    wenzi 評(píng)論0 收藏0
  • 面試中關(guān)于Redis的問(wèn)題看這篇就夠了

    摘要:所以查閱官方文檔以及他人造好的輪子,總結(jié)了一些面試和學(xué)習(xí)中你必須掌握的問(wèn)題。在微博應(yīng)用中,可以將一個(gè)用戶(hù)所有的關(guān)注人存在一個(gè)集合中,將其所有粉絲存在一個(gè)集合。 昨天寫(xiě)了一篇自己搭建redis集群并在自己項(xiàng)目中使用的文章,今天早上看別人寫(xiě)的面經(jīng)發(fā)現(xiàn)redis在面試中還是比較常問(wèn)的(筆主主Java方向)。所以查閱官方文檔以及他人造好的輪子,總結(jié)了一些redis面試和學(xué)習(xí)中你必須掌握的問(wèn)題。...

    yanbingyun1990 評(píng)論0 收藏0
  • Lombok 看這篇就夠了

    摘要:注解在類(lèi)上為類(lèi)提供一個(gè)全參的構(gòu)造方法,加了這個(gè)注解后,類(lèi)中不提供默認(rèn)構(gòu)造方法了。這個(gè)注解用在類(lèi)上,使用類(lèi)中所有帶有注解的或者帶有修飾的成員變量生成對(duì)應(yīng)的構(gòu)造方法。 轉(zhuǎn)載請(qǐng)注明原創(chuàng)地址:http://www.54tianzhisheng.cn/2018/01/07/lombok/ showImg(http://ohfk1r827.bkt.clouddn.com/blog/180107/7...

    LeanCloud 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<