當前位置:成語大全網 - 書法字典 - 專家系統實現了數百萬數據的快速檢索。

專家系統實現了數百萬數據的快速檢索。

當用戶點擊壹個購買商品時,該商品的所有相關內容將被匹配。所有數據都存在於ES中,數量級為百萬。嗯~我想用python寫壹個接口。可以通過查找數據和專家系統模糊搜索來實現。

前綴的匹配壹般是處理沒有分割的場景,會匹配articleID中以“j”開頭的doc。Prefix不計算相關性分數,只執行過濾操作。與filter的唯壹區別是filter緩存結果,而prefix不緩存。前綴越短,要處理的doc越多,性能越差。

?匹配任何字符,而*匹配0個或更多字符。性能根前綴也壹樣糟糕,必須掃描整個倒排索引。

[0-9]:指定範圍內的數字。

【a-z】:指定範圍內的字幕。

。:壹個字符。

+:前面的正則表達式可以出現壹次或多次。

常規搜索也會掃描整個表,性能會比較差。

模糊性參數的數量調整和修正

通常不會直接使用上面的搜索,但會使用下面的搜索:

在專家系統中,組合條件查詢的使用是搜索引擎搜索數據的壹個有力組成部分。在以前的文章中,簡單地演示了es的查詢語法,但是添加、刪除和修改查詢的基本功能並不能很好地滿足復雜的查詢場景。比如我們期望像mysql壹樣用復雜的條件進行查詢,該怎麽辦?es裏有壹個語法叫bool。通過在bool中拼接es特定的文法,可以做大多數場景下復雜條件的拼接查詢,也叫復合查詢。

首先簡單介紹了專家系統中組合查詢常用的關鍵字。

過濾:過濾,不參與評分。

必須:如果有多個條件,它們必須滿足and和。

Should:如果有多個條件,其中壹個或多個可以是or或OR。

Must_not:與Must相反,必須不滿足所有條件才可以匹配!表示“不”

事件描述

必須

該子句(查詢)必須出現在匹配的文件中,並且將有助於得分。

過濾器

子句(查詢)必須出現在匹配的文檔中。然而,不同於must查詢的分數將被忽略。Filter子句在過濾器上下文中執行,這意味著分數被忽略,並且該子句被考慮用於緩存。

應該

子句(查詢)應該出現在匹配的文檔中。如果bool查詢在查詢上下文中,並且有壹個mustor filter子句,那麽即使沒有匹配的should查詢,文檔也會匹配bool查詢。在這種情況下,這些術語僅用於影響分數。如果bool查詢是壹個篩選器上下文,或者兩者都不存在,則至少有壹個must或filter的should查詢必須與文檔匹配,以匹配bool查詢。這種行為可以通過設置minimum_should_match參數來顯式控制。

千萬不要

子句(查詢)不能出現在匹配的文檔中。該子句在過濾器上下文中執行,這意味著分數被忽略,並且該子句被考慮用於緩存。由於分數被忽略,返回了0的所有文件的分數。

讓我們用實驗來演示上述查詢的相關語法。

1.首先,我們創建壹個索引,並向其中添加壹些數據供以後使用。

我可以在這裏直接批量插入數據,也可以通過PUT的語法插入。

帖子/論壇/文章/_批量

{ "index": { "_id": 1 }}

{ " articleID ":" XHDK-A-1293-# fJ3 "," userID" : 1," hidden": false," postDate ":" 2019-07-01 "," title":"java包含hadoop和spark "," topic":"java" }

{ "index": { "_id": 2 }}

{ "articleID" : "KDKE-B-9947-#kL5 "," userID" : 1," hidden": false," postDate": "2019-07-02 ",title":"php包含admin "," topic":"java和php" }

{ "index": { "_id": 3 }}

{ " articleID ":" JODL-X-1937-# pV7 "," userID" : 2," hidden": false," postDate": "2019-07-03 ",title":"spark是新語言"," topic":"spark可能使用java"}

{ "index": { "_id": 4 }}

{ "articleID" : "QQPX-R-3956-#aD8 "," userID" : 2," hidden": true," postDate": "2019-07-04 ",title":"hadoop可能涉及java "," topic ":"使用的大數據" }

或者使用put語法。

放/論壇/文章/4

{

" articleID": "QQPX-R-3956-#aD8 ",

“userID”:2,

“隱”:真,

" postDate": "2019-07-04 ",

"標題":" hadoop可能涉及java ",

“主題”:“使用大數據”

}

4條數據已成功插入。

2、$ TERM查詢、$ TERM查詢不分詞,這類似於mysql中的where filedName =?語法,也就是精確匹配,比如我們查詢articleid = xhdk-a-1293-# fj3的這個數據。

獲取/論壇/文章/_搜索

{

"查詢":{

"期限":{

" articleid . keyword ":" XHDK-A-1293-# fJ3 "

}

}

}

2.必須查詢,即查詢條件中必須匹配的字段。例如,查詢標題必須包含java數據。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"必須":[

{"term":{"title":"hadoop"}}

]

}

}

}

找出兩個數據

如果是應該呢?以下語法,即查詢標題中包含hadoop或主題中包含spark,其中壹個即可滿足。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"應該":[

{"term":{"title":"hadoop"}},

{ "術語":{ "主題":"火花" }}

]

}

}

}

找到了三條數據,

Must和should壹起使用,

最後,壹個更復雜的嵌套查詢,我們先來看看這個sql語句。

選擇*

來自論壇.文章

其中article _ id = ' XHDK-A-1293-# fJ3 '

或者(article _ id = ' JODL-X-1937-# pV7 '和post _ date = ' 2017-01-01 '),

轉換成es對應的復合查詢語法是什麽?在拆分方面,它是壹個should語句的嵌套。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"應該":[

{

"期限":{

" articleid . keyword ":" XHDK-A-1293-# fJ3 "

}

},

{

" bool": {

"必須":[

{

"期限":{

" articleid . keyword ":" JODL-X-1937-# pV7 "

}

},

{

"期限":{

" post date ":" 2019-07-01 "

}

}

]

}

}

}

}

按照這個思路,如果不知道如何為壹個復雜的查詢構造查詢語句,可以考慮先按照sql的語法進行拆分,然後組織es查詢語句就是壹個很好的突破口。

此時,我們可能會有疑問,復合條件下的$ term查詢和簡單匹配有什麽區別?既然都是查詢,原理上有什麽區別?

我們知道匹配查詢需要全文檢索,而且是全文檢索。當然,如果搜索的字段值不是_analyzed,那麽匹配查詢相當於$ term查詢。例如,在下面的搜索中,因為我們在插入數據時沒有指定title字段,所以默認情況下它是text類型,並且它將被自動分段,所以只要hadoop包含在title中,它就可以被匹配。

獲取/論壇/文章/_搜索

{

"查詢":{

"匹配":{

"標題":" hadoop "

}

}

}

2.在某些情況下,如果我們直接使用match進行查詢,並且希望查詢出來的結果有我們期望的那麽多關鍵詞,那麽我們可以在使用match進行匹配時添加其他條件,以提高結果的匹配精度。

獲取/論壇/文章/_搜索

{

"查詢":{

"匹配":{

"標題":{

「查詢」:「java hadoop」,

“運算符”:“和”

}

}

}

}

匹配的結果包含更多我們期望的關鍵詞,也就是說,我們的查詢結果中包含的關鍵詞可以在查詢中指定。

Es還有其他的語法來達到上面的效果,minimum_should_match。通過這個語法,可以指定匹配的百分比,也就是查詢的關鍵字至少要達到的百分比。下面這個表示所有匹配,只找到壹個結果。

如果我們降低百分比,比如說75%,我們可以看到兩個結果。

3.當然我們也可以把bool和match壹起用,如下。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"必須":[

{"match": {"title": "java"}}

],

"壹定不能":[

{ "匹配":{ "標題":"火花" }}

]

,“應該”:[

{

"匹配":{

"標題":" php "

}

}

]

}

}

}

這樣,我們也可以更準確地匹配我們期望的查詢結果。

綜上所述,當我們使用match進行查詢時,如果查詢字段包含多個單詞,比如下面這個,

{

" match ":{ " title ":" Java elastic search " }

}

實際上,es會自動將這個匹配查詢轉換成底部的bool Should,指定多個搜索詞,同時使用$ term查詢。轉換後的語法如下。

{

" bool": {

"應該":[

{ "term": { "title": "java" }},

{ " term ":{ " title ":" elastic search " } }

]

}

}

上面提到的with and in match查詢對應的是bool查詢,轉換後的語法如下:$ term+must,

{

"匹配":{

"標題":{

「查詢」:「java elasticsearch」,

“運算符”:“和”

}

}

}

{

" bool": {

"必須":[

{ "term": { "title": "java" }},

{ " term ":{ " title ":" elastic search " } }

]

}

}

對於minimum_should_match的語法,道理也差不多。

{

"匹配":{

"標題":{

「查詢」:「java elasticsearch hadoop spark」,

" minimum_should_match": "75% "

}

}

}

{

" bool": {

"應該":[

{ "term": { "title": "java" }},

{ " term ":{ " title ":" elastic search " } },

{ "term": { "title": "hadoop" }},

{ "term": { "title": "spark" }}

],

“最小_應該_匹配”:3

}

}

我們來看壹個具體的操作例子,也就是說,必須包含至少三個關鍵詞的數據才會出現在搜索結果中。

3.在搜索中,我們有這樣壹個需求,搜索結果中包含java,如果標題中包含hadoop或者spark,就會被優先搜索。同時,如果壹個帖子包含java hadoop,壹個帖子包含java spark,那麽包含hadoop的帖子會比spark先被搜索到。

對於這樣的需求,壹般來說,需要增加某些搜索條件的權重,讓更多符合和滿足我們業務場景的數據在搜索結果中被搜索出來,在es中通過boost關鍵字增加搜索條件的權重。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"必須":[

{

"匹配":{

"標題":" java "

}

}

],

"應該":[

{

"匹配":{

"標題":{

"查詢":" hadoop "

}

}

},

{

"匹配":{

"標題":{

「查詢」:「火花」,

【助推】:2

}

}

},

{

"匹配":{

"標題":{

"查詢":" php "

}

}

},

{

"匹配":{

"標題":{

「查詢」:「hadoop」,

【助推】:5

}

}

}

]

}

}

}

上面的例子意味著我們對hadoop被包含在搜索的標題中的條件給予更多的權重,hadoop的結果將被限制為被搜索。

4、dis_max語法,也稱為best_field,在某些情況下,如果我們在bool查詢中使用多個字段,但查詢是相同的,可能會導致查詢結果沒有按照我們期望的字段排在前面,即我們只需要將指定字段的內容顯示在前面,如下。

獲取/論壇/文章/_搜索

{

"查詢":{

" bool": {

"應該":[

{ "match": { "title": "java解決方案" }},

{ "match": { "content": "java解決方案" }}

]

}

}

}

標題和內容的搜索條件相同,但是我們希望結果中的標題包含java解決方案的前置顯示,但是直接查詢可能達不到預期的效果。如果使用dis_max進行拼接,

獲取/論壇/文章/_搜索

{

"查詢":{

" dis_max": {

"查詢":[

{ "match": { "title": "java解決方案" }},

{ "match": { "content": "java解決方案" }}

]

}

}

}

這樣,查詢結果更符合期望值,

5.但是使用dis_max,只取壹個查詢的最大值,其他查詢的分數完全忽略。即如果壹個結果在包標題中包含java,而在主題中沒有,另壹個則相反,結果是兩個都包含java。在dis_max文法下,只會得到相關性分數最高的壹個,其他結果不予考慮。此時,如果需要獲取其他包含java的title或topic的結果,可以使用tie_breaker進行進壹步的打包,如下。

獲取/論壇/文章/_搜索

{

"查詢":{

" dis_max": {

"查詢":[

{ "匹配":{ "標題":"火花" }},

{ "match": { "topic": "java"}}

],

“平局決勝”:0.6

}

}

}

這樣,發現了三個結果。總體來說,還是需要結合實際的業務場景來使用。然而,大多數情況下,我們是相愛的。我們還是希望根據我們給定的條件,搜索結果優先考慮包含更多關鍵詞的內容。