1. 程式人生 > >ElasticSearch——搜尋機制

ElasticSearch——搜尋機制

在個人的實踐中,ElasticSearch是充當關係型資料庫來使用,將Mysql中資料過大的超過1000w的表存入ES中,所以使用的全部是確切詞查詢而非全文檢索,因此在本次ES的學習中忽略了與全文檢索相關如得分等相關特性,這些在後續的有關搜尋引擎的實踐中會介紹。

在這張腦圖中主要介紹的是搜尋相關的一些機制。下面會對該圖做一些簡單的說明。

簡單查詢

前文說過ES的操作都是基於JSON來控制的,那麼不管是簡單的查詢還是複雜的查詢ES都是通過不同的JSON物件來實現的。
這裡只是簡單的說明,通過腦圖方便記憶,具體的操作可以看ElasticSearch—— Java API

查詢過程

  • 查詢邏輯

    1. 發散階段:
    2. 收集階段:
  • 搜尋型別

    查詢執行的順序,方式等,預設的是query_then_fetch,此方式符合上述的查詢邏輯,現在所有分片上面進行查詢對文件的排序和分級資訊,然後再在相應的分片上面進行查詢實際的文件。
    還有一些其他的型別如query_and_fetch,dfs_query_and_fetch,dfs_query_then_fetch等等,可以在搜尋時進行指定:

    http://localhost:9200/index/search?pretty=true&search_type=query_and_fetch
    複製程式碼
  • 搜尋執行的偏好

    控制查詢發生在主片還是副本上面,由preference=xxxx指定

    http://localhost:9200/index/_search?preference=_primary
    複製程式碼

    只在主分片上執行搜尋,不使用副本。當想使用索引中最近更新的、還沒複製到副本 中的資訊,這個是很有用的。

基本查詢

ES中的查詢分很多種類,這邊說明幾種常見的使用方式

  • 詞條查詢

    它僅匹配在給定欄位中含有該詞條的文件,而 且是確切的、未經分析的詞條

{
    "query" : {
        "term" : {
            "title" : "crime"
        }
    }
}
複製程式碼

如上上述查詢將匹配title欄位中含有crime一詞的文件。記住,詞條查詢是未經分析的,因此需 要提供跟索引文件中的詞條完全匹配的詞條
而這種方式和傳統SQL中的"="(等值)語句效果一樣。

  • 多詞條查詢

    詞條查詢允許匹配單個未經分析的詞條,多詞條查詢可以用來匹配多個這樣的詞條。

    {
        "query" : {
            "terms" : {
                "tags" : [ "novel", "book","hello" ],
                "minimum_match" : 1
            }
        }
    }
    複製程式碼

    如上,上述查詢返回在tags欄位中包含一個或兩個搜尋詞條的所有文件。為什麼?這是因為我們 把minimum_match屬性設定為1;這意味著至少有1個詞條應該匹配。如果想要查詢匹配所有詞 條的文件,可以把minimum_match屬性設定為2。
    當minimum_match=1時就和SQL中的“in“語句類似了。

  • 範圍查詢

    範圍查詢使我們能夠找到在某一欄位值在某個範圍裡的文件,欄位可以是數值型,也可以是基於字串的(將對映到一個不同的Apache Lucene查詢),範圍查詢只能針對單個欄位。

    {
        "query" : {
            "range" : {
                "year" : {
                    "gte" : 1700,
                    "lte" : 1900
                }
            }
        }
    }
    複製程式碼

    找到year欄位從1700到1900的所有圖書
    類似SQL中的">","<",">=","<="

複合查詢

複合查詢就是支援可以把多個查詢連線起來,或者改變其他查詢的行為。

  • 布林查詢

    複合查詢就是支援可以把多個查詢連線起來,或者改變其他查詢的行為 主要有如下幾種連線符。

    1. must :被它封裝的布林查詢必須被匹配,文件才會返回 類似"and"
    2. should :被它封裝的布林查詢可能被匹配,也可能不被匹配 類似"or"
    3. must_not:被它封裝的布林查詢必須不被匹配,文件才會返回 類似 "!="
{
    "query" : {
        "bool" : {
            "must" : {
                "term" : {
                    "title" : "crime"
                }
            },
            "should" : {
                "range" : {
                    "year" : {
                        "from" : 1900,
                        "to" : 2000
                    }
                }
            },
            "must_not" : {
                "term" : {
                    "otitle" : "nothing"
                }
            }
        }
    }
}    
複製程式碼

找到所有這樣的文件:在title欄位中含有crime詞條,並且year欄位可以在 也可以不在1900~2000的範圍裡,在otitle欄位中不可以包含nothing詞條。

查詢結果的過濾

過濾器是可以在查詢的結果中做過濾,比如在不影響最後分數的情況下,選擇索引中的某個子集,就可以使用過濾器。
一般來說應該儘可能使用過濾器。過濾器不影響評分,而得分計算讓搜尋變得複雜,而且需要CPU資源。另一方面,過濾是一種相對簡單的操作。由於過濾應用在整個索引的內容上,過濾的結果獨立於找到的文件,也獨立於文件之間的關係。過濾器很容易被快取,從而進一步提高過濾查詢的整體效能。

過濾器發生在執行查詢之前,所以效能比較好,應該儘可能的使用過濾器

{
 "query": {
     "filtered" : {
         "query" : {
             "match" : { 
                 "title" : "Catch-22" 
             }
         },
         "filter" : {
             "term" : { 
                 "year" : 1961 
                 
             }
         }
     }
 }
}
複製程式碼

在title欄位搜尋Catch-22並向其新增過濾器表示只要year=1961的文件。
常見過濾器

  • term過濾器
  • terms過濾器
  • and過濾器
  • or過濾器
  • bool過濾器 ······

未完待續!!!!!!