Elasticsearch系列(5):深入搜索


結構化搜索

結構化搜索是指搜索那些具有內置結構數據的過程,比如日期,時間和數字都是結構化的,它們有精確的格式,我們可以對這些格式進行邏輯操作,比較常見的操作包括比較數字或時間的范圍,或判定兩個值的大小。

在結構化搜索中,我們得到的結果總是非是即否,要么存在於集合之中,要么存在於集合之外,結構化查詢不關心文件的相關度或評分,它簡單的對文檔包括或排除處理。

這在邏輯上是能說通的,因為一個數字不能比其它數字更適合存在於某個相同的范圍,結果只能是:存在於范圍之中,抑或反之,同樣,對於結構化文本來說,一個值要么相等,要么不相等,沒有更似這種概念。

當進行精確值搜索時,我們會使用過濾器(filter),過濾器很重要,因為它們執行速度非常快,不會計算相關度(直接跳過了整個評分階段)而且很容易被緩存,所以,要盡可能多的使用過濾器搜索。

一,精確值搜索

說到精確值搜索,一定會使用到term查詢,它可以處理數字(number),日期(date),布爾值(bool)和文本(text)。

1,term查詢數字

比如,我要查詢價格為20元的所有產品,我們可以使用term查詢來實現需求,查詢語句為:

GET /my_store/products/_search
{
  "query": {
    "term": {
      "price": {
        "value": "20"
      }
    }
  }
}

通常當查找一個精確值的時候,我們不希望對查詢進行評分計算,只希望對文檔進行包括或排除的計算,所以我們會使用constant_score查詢以非評分模式進行term查詢並以1作為統一評分,使用constant_score之后的查詢語句為:

GET /my_store/products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "price": "20"
        }
      }
    }
  }
}

從以上查詢語句可以總結出:

  • 通常使用constant_score將term查詢轉化為過濾器filter。
  • 查詢置於filter語句內還進行評分和相關度的計算,所有的結果都會返回一個默認的評分1。

2,term查詢文本

term查詢文本和查詢數字一樣容易,比如,我們要查詢ID為’XHDK-A-1293-#fJ3’的產品,查詢語句為:

GET /my_store/products/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "productID": "XHDK-A-1293-#fJ3"
        }
      }
    }
  }
}

注意:

如果文本中帶有元字符(比如連字符-和哈希符#),默認是查詢不出任何結果的,原因是索引數據的方式不同,productID被拆分成了多個更小的token。為了避免這種問題,我們需要告訴es該字段具有精確值,要將其設置成not_analyzed無需分析的,再去查詢就能得到正確的結果了。

二,組合過濾器

前面的例子都是單個過濾器(filter)的使用方式,但是在實際業務場景中,我們很有可能會過濾多個值或字段,這個時候就會用到布爾過濾器。

1,布爾過濾器

一個bool過濾器由三個部分組成:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
   }
}

must:表示所有的語句都必須匹配,相當於sql里的and。

must_not:表示所有的語句都不能匹配,相當於sql里的not。

should:表示至少有一個語句要匹配,相當於sql里的or。

注意:

一個bool過濾器的每個部分都是可選的,而且每個部分內容都可以只有一個或一組過濾器。

比如,我們要查詢價格為20元同時productID為“XHDK-A-1293-#fJ3”,且價格不為30元的產品,使用布爾過濾器的查詢語句為:

GET /my_store/products/_search
{
   "query" : {
      "filtered" : { 
         "filter" : {
            "bool" : {
              "should" : [
                 { "term" : {"price" : 20}}, 
                 { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} 
              ],
              "must_not" : {
                 "term" : {"price" : 30} 
              }
           }
         }
      }
   }
}

注意:

  • 需要使用filtered查詢將所有的東西包起來。
  • 在should語句塊里面的兩個term過濾器與bool過濾器是父子關系,兩個term條件需要匹配其一。
  • 在must_not語句塊里,如果一個產品的價格是30元,那么它會自動被排除,因為它處於must_not語句里面。

2,嵌套布爾過濾器

//filtered不被支持???

三,查找多個精確值


四,范圍


五,處理NULL值



全文搜索


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM