1. 程式人生 > >ElasticStack學習(六):ElasticSearch搜尋初探

ElasticStack學習(六):ElasticSearch搜尋初探

一、ElasticSearch搜尋介紹

  1、ElasticSearch搜尋方式主要分為以下兩種:

    1)、URI Search:此種查詢主要是使用Http的Get方法,在URL中使用查詢引數進行查詢;

    如:http://localhost:9200/kibana_sample_data_ecommerce/_search?q=customer_first_name:Jim

    這條URL中,q表示查詢的內容,用來搜尋名叫Jim的客戶。用Postman進行查詢,搜尋結果如下圖所示:

    

     2)、Request Body Search(DSL查詢):此種查詢是使用ElasticSearch提供的,可以採用Get或Post的方法,基於JSON格式的更加完備的DSL(Query Domain Specific Language);

    如:http://localhost:9200/kibana_sample_data_ecommerce/_search 

    在請求體中寫入:    

{
    "query":{"match_all":{}}
}

    其中match_all代表返回所有的文件。  

    或同樣查詢customer_first_name:Jim,如下: 

{
    "profile": true,
    "query": {
        "match": {"customer_first_name":"Jim"}
    }
}

    用Postman進行查詢,結果如下圖所示:

    took表示查詢用時;hits表示查到了多少結果,ElasticSearch預設列出10條;_score表示相關度評分;_source表示文件原始資訊;

    所以,大體上可根據以下語法進行查詢:  

/_search 
查詢範圍:叢集上所有的索引;

/index-name1/_search
查詢範圍:只查詢index-name1索引;

/index-name1,index-name2/_search
查詢範圍:查詢index-name1,index-name2兩個索引;

/index*/_search
查詢範圍:查詢以index開頭的索引;

   2、搜尋相關性

  搜尋是使用者與搜尋引擎的對話,比較關注的有如下幾點:

    1)是否可以找到所有相關的內容;

    2)有多少不相關的內容被返回了;

    3)文件的打分是否合理;

    4)結合業務需求,平衡結果排名;  

  3、搜尋結果的衡量

    1)Precision-查準率:儘可能返回較少的無關文件,公式為:返回的相關結果/(返回的相關結果+返回的無關結果)

    2)Recall-查全率:儘量返回較多的相關文件,公式為:返回的相關結果/(返回的相關結果+應該返回但沒有返回結果)

    3)Ranking-排名:是否能夠按照相關度進行排序;

 二、ElasticSearch URI搜尋操作

  通過URI Query實現搜尋,語法如下:  

Get /movies/_search?q=2012&df=title_name&sort=year:desc&from=0&size=10&timeout=1s
{
  "profile":true
}

    q:指定的查詢語句,使用Query String 語法;

  df:預設欄位,若不指定,會對所有欄位進行查詢;

  sort:用於排序;

  from、size:用於分頁;

  profile:用於展示查詢是如何被執行的;

  1、指定欄位查詢、泛查詢

  指定欄位查詢:就是查詢的值是在某個欄位範圍內進行的查詢。對movies索引中的title欄位做2012資訊的查詢,查詢結果如下圖所示:

  

  泛查詢:就是查詢的值是對索引中所有欄位進行匹配,如下圖所示:

   

  2、Term【詞語】查詢與Phrase【短語】查詢

  兩者區別在於,若要查詢一條資訊,如Iron Man

  對於Term查詢,Iron Man等效於Iron OR Man;

  對於Phrase查詢,“Iron Man"等效於Iron AND Man,而且要求前後順序要保持一致;

  注意:對於Term查詢,需要加上括號才可以;對於Phrase查詢,需要加上引號才可以;

  如下圖所示:

  

  

  3、布林查詢

  布林表示符:AND/OR/NOT(+、-),注意:符號必須大寫。具體操作如下圖所示:

  

  在AND查詢中,我們會發現查詢出8條結果,與Phrase查詢結果並不相同。原因在於:Phrase查詢要求查詢資訊前後順序必須是一致的,而AND查詢並沒有這個要求,因此多出兩條查詢資料。

  

  在OR查詢中,我們會發現與Term查詢結果是相同的,包括profile中所列出的description都是一樣的。不相同的是查詢型別,Term查詢是TermQuery,Or查詢是BooleanQuery。

  

  4、範圍查詢

  []:表示閉區間;{}:表示開區間;如下圖所示:

  

  

  上圖中,開區間查詢,在profile中會發現,查詢範圍是從2016至2019,開區間意味著要大於開區間的起始值。

  5、算數符號查詢

  包括:>、>=、<、<=,如下圖所示:

  

   

  6、萬用字元查詢

  萬用字元查詢效率低、佔用記憶體大,故不建議使用。

  ?:代表1個字元;*:代表0或多個字元;

  

  

  7、模糊/近似度匹配查詢

  

  

  從上面兩圖中可以看出,近似度查詢中的~1表示一個詞中允許有一個字母與正確單詞不差別;~2表示對一個短語進行搜尋,可以搜尋到缺失1個或2個詞的短語,2個以上的不屬於此搜尋範圍。

  8、正則表示式查詢

三、Request Body搜尋操作(DSL操作)

  在ElasticSearch中,一般高階的搜尋操作都是通過Request Body來實現。

//通過from size返回查詢結果,注意:獲取靠後的翻頁成本較高。
post /movies/_search
{
    "profile": true,
    “from":10,
    "size":20,
    "query": {
        "match": {"title":"iron man"}
    }
}
//通過sort對查詢結果進行排序,注意:排序欄位最好是“數字型”或“日期型”
post /movies/_search
{
    "profile": true,
    "sort":[{"order_date":"desc"}]
    "from":10,
    "size":20,
    "query": {
        "match": {"title":"iron man"}
    }
}  
//通過_source元資料過濾,返回相應的欄位,此時,對"iron man"的查詢是iron OR man的邏輯
post /movies/_search
{
  "profile":true,
  "_source":["title","year"],
  "from":10,
  "size":5,
  "sort":[{"year":"desc"}],
  "query":{
    "match": {"title":"iron man"}
  }
}
//若想對"iron man"執行iron AND man的邏輯,可按如下操作
post /movies/_search
{
  "profile":true,
  "_source":["title","year"],
  "from":10,
  "size":5,
  "sort":[{"year":"desc"}],
  "query":{
    "match"{
    "title":{
      "query":"iron man",
      "operator":"AND"
     }
   }
  }
}

   兩者執行結果,如下圖所示:

  

//指令碼欄位,通過script_fields對返回欄位進行加工,來算出一個新的欄位
post /movies/_search
{
  "profile":true,
  "script_fields":{
    "new_fields":{
      "script":{
        "lang":"painless",
        "source":"doc['year'].value+'-hello'"
        }
      }
    },
  "_source":["title","year"],
  "from":0,
  "size":10,
  "sort":[{"year":"desc"}],
  "query":{
    "match_all":{}
    }
}

   

//短語搜尋,注意slop的意思是可以在iron man之間可以有1個其他的字元
post /movies/_search
{
  "profile":true,
  "_source":["title","year"],
  "query":{
    "match_phrase":{
        "title":{
            "query":"iron man",
            "slop":"1"
          }
      }
    }
}

   

四、Query String和Simple Query String搜尋(也是DSL操作)

  我們向索引users中插入兩條文件:

put /users/_doc/3
{
  "name":"tang bohu",
  "about":"gongfu,wencai,huahua"
}
put /users/_doc/4
{
  "name":"zhang sanfeng",
  "about":"gongfu,youmo"
}

   1、Query String

  在DSL中也是可以支援類似於URI Query的查詢。

  

  2、Simple Query String

  該種查詢的特點:

  1)此種查詢類似於Query String,但是會忽略錯誤的語法,同時只支援部分查詢語法;

  2)不支援AND、OR、NOT,只會將其作為字串處理;

  3)Term之間的預設關係是OR,通過Operator可以指定其他關係;

  4)支援部分邏輯:+、-、|;

  

  

  注意:Query、Query String、Simple Query String在使用時,後兩者的靈活性降低了,但是更容易寫;而第一種靈活性最大,但是容易出錯。

  

  大家可關注我的公眾號

   

  知識學習來源:阮一鳴:《Elasticsearch核心技術與實戰》 &n