Elasticsearch核心技術與實戰學習筆記 第四章 27 | Query&Filtering與多字符串多字段查詢

一 序

   本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。

二 Query Context & Filter Context

  高級搜索的功能,支持多想文本輸入,針對多個字段進行搜索
搜索引擎一般也提供時間,價格等條件過濾
在 ES 中,有 Query 和 Filter 兩種 Context
Query Context :相關性算分
Filter Context :不需要算分(YES OR NO), 可以利用 Cache 獲得更好的性能

條件組合

假設搜索一本電影

  • 評論中包含了 Guitar ,用戶打分高於 3 分,同時上映時間在 1993 到 2000 年之間

這個搜索包含了 3 段邏輯,針對不同的字段

  • 評論字段中要包含 Guitar 、用戶評論大於 3、上映時間日期在給定範圍內

同時包含這三個邏輯,並且有比較好的性能

  • 複合查詢: bool Query

bool 查詢

 

一個 bool 查詢,是一個或者多個查詢子句的組合

  • 總共包含 4 種子句,其中 2 種會影響算分,2 種不影響算分

相關性並不只是全文本搜索的專利。也適合 yes | no 的子句,匹配的子句越多,相關性評分越高。如果多條查詢子句被合併爲一條複合查詢語句,比如 bool 查詢,則每個查詢子句計算得出的評分會被合併到總的相關性評分中。

bool 查詢語句

  • 子查詢可以任意順序出現
  • 可以嵌套多個查詢
  • 如果你的 bool 查詢中,沒有 must 條件,should 中必須滿足一條查詢

準備數據

POST /products/_bulk
{ "index": { "_id": 1 }}
{ "price" : 10,"avaliable":true,"date":"2018-01-01", "productID" : "XHDK-A-1293-#fJ3" }
{ "index": { "_id": 2 }}
{ "price" : 20,"avaliable":true,"date":"2019-01-01", "productID" : "KDKE-B-9947-#kL5" }
{ "index": { "_id": 3 }}
{ "price" : 30,"avaliable":true, "productID" : "JODL-X-1937-#pV7" }
{ "index": { "_id": 4 }}
{ "price" : 30,"avaliable":false, "productID" : "QQPX-R-3956-#aD8" }

這是一個bool搜索的例子,條件:價格是30.filter對算分無影響,對應的條件是true.must_not 對算分無影響。should的條件id滿足兩個之一。

如何解決結構化查詢 -“包含而不是相等” 的問題

增加 count 字段,使用 bool 查詢

#改變數據模型,增加字段。解決數組包含而不是精確匹配的問題
POST /newmovies/_bulk
{ "index": { "_id": 1 }}
{ "title" : "Father of the Bridge Part II","year":1995, "genre":"Comedy","genre_count":1 }
{ "index": { "_id": 2 }}
{ "title" : "Dave","year":1993,"genre":["Comedy","Romance"],"genre_count":2 }
#must,有算分
POST /newmovies/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"genre.keyword": {"value": "Comedy"}}},
        {"term": {"genre_count": {"value": 1}}}

      ]
    }
  }
}

must 有算分 

Filter。不參與算分,結果的score是0 

should  影響算分:對比前面可見這個分數高了。

bool 嵌套

#嵌套,實現了 should not 邏輯
POST /products/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "price": "30"
        }
      },
      "should": [
        {
          "bool": {
            "must_not": {
              "term": {
                "avaliable": "false"
              }
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

查詢語句的結構,會對相關度算分產生影響

  • 同一層級下的競爭字段,具有相同的權重
  • 通過嵌套 bool 查詢,可以改變對算分的影響

上面例子,左側相同的權重,對比下右側的,我們吧顏色該寫到子查詢,會影響到算分。

控制字段的 Boosting

demo:

DELETE blogs
POST /blogs/_bulk
{ "index": { "_id": 1 }}
{"title":"Apple iPad", "content":"Apple iPad,Apple iPad" }
{ "index": { "_id": 2 }}
{"title":"Apple iPad,Apple iPad", "content":"Apple iPad" }

1 先調整title的boost,返回對應2再前面 

如果調整body的boost: 文檔1會在前面

demo2:搜索新聞的例子

DELETE news
POST /news/_bulk
{ "index": { "_id": 1 }}
{ "content":"Apple Mac" }
{ "index": { "_id": 2 }}
{ "content":"Apple iPad" }
{ "index": { "_id": 3 }}
{ "content":"Apple employee like Apple Pie and Apple Juice" }

插入3條數據,要求搜索蘋果公司的產品優先。

默認條件的搜索,不是符合預期。

加入must_not做過濾。返回2條。

通過調整boost,返回順序也做了調整。 

 小結

  • Query Context vs Filter Context
  • Bool Query - 更多的條件組合
  • 查詢結構與相關性算分
  • 如何控制查詢的精確度
    • Boosting & Boosting Query
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章