ElasticSearch7.3學習(二十一)----Filter與Query對比、使用explain關鍵字分析語法

|舊市拾荒|發表於2022-04-19

1、資料準備

首先建立book索引

PUT /book/
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "description": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "studymodel": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "timestamp": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "pic": {
        "type": "text",
        "index": false
      }
    }
  }
}

插入資料

PUT /book/_doc/1
{
  "name": "Bootstrap開發",
  "description": "Bootstrap是一個非常流行的開發框架。此開發框架可以幫助不擅長css頁面開發的程式人員輕鬆的實現一個css,不受瀏覽器限制的精美介面css效果。",
  "studymodel": "201002",
  "price": 38.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "bootstrap",
    "dev"
  ]
}

PUT /book/_doc/2
{
  "name": "java程式設計思想",
  "description": "java語言是世界第一程式語言,在軟體開發領域使用人數最多。",
  "studymodel": "201001",
  "price": 68.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "java",
    "dev"
  ]
}

PUT /book/_doc/3
{
  "name": "spring開發基礎",
  "description": "spring 在java領域非常流行,java程式設計師都在用。",
  "studymodel": "201001",
  "price": 88.6,
  "timestamp": "2019-08-24 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "spring",
    "java"
  ]
}

2、Filter與Query示例

需求:使用者查詢description中有"java程式設計師",並且價格大於80小於90的資料。

2.1 Query

首先採用Query來進行查詢,首先查詢description中有"java程式設計師"。

GET /book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "java程式設計師"
          }
        }
      ]
    }
  }
}

查詢結果如下:

ElasticSearch7.3學習(二十一)----Filter與Query對比、使用explain關鍵字分析語法

可以看到,查詢出來兩條資料,score分別是1.9、0.5。

然後查詢description中有"java程式設計師",並且價格大於80小於90的資料

GET /book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "java程式設計師"
          }
        },
        {
          "range": {
            "price": {
              "gte": 80,
              "lte": 90
            }
          }
        }
      ]
    }
  }
}

再次檢視結果:

ElasticSearch7.3學習(二十一)----Filter與Query對比、使用explain關鍵字分析語法

這次查詢出來一條資料,score變為2.9。這一條資料在上一次的查詢結果中的score為1.9。然後接著往下看使用Filter。

2.2 filter

還是相同的需求,首先查詢description中有"java程式設計師"。

GET /book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "java程式設計師"
          }
        }
      ]
    }
  }
}

查詢結果如下:

ElasticSearch7.3學習(二十一)----Filter與Query對比、使用explain關鍵字分析語法

通過查詢結果可以看到,查詢的兩條資料的score是1.9、0.5。

然後使用filter查詢description中有"java程式設計師",並且價格大於80小於90的資料

GET /book/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "java程式設計師"
          }
        }
      ],
      "filter": {
        "range": {
          "price": {
            "gte": 80,
            "lte": 90
          }
        }
      }
    }
  }
}

查詢結果如下:

ElasticSearch7.3學習(二十一)----Filter與Query對比、使用explain關鍵字分析語法

可以看到,查詢出來的資料與使用query查詢結果一樣,但是score依舊為1.9。

說明在使用query查詢的過程中,影響到了相關度(score)的排序,在使用filter進行查詢,並不會影響相關度(score)的計算。

2.3  filter與query對比

filter,僅僅只是按照搜尋條件過濾出需要的資料而已,不計算任何相關度分數,對相關度沒有任何影響。

query,會去計算每個document相對於搜尋條件的相關度,並按照相關度進行排序。

應用場景:

一般來說,如果你是在進行搜尋,需要將最匹配搜尋條件的資料先返回,那麼用query。如果你只是要根據一些條件篩選出一部分資料,不關注其排序,那麼用filter。

2.4 filter與query效能

filter,不需要計算相關度分數,不需要按照相關度分數進行排序,同時還有內建的自動cache最常使用filter的資料。比如在範圍查詢,keyword欄位查詢中推薦使用filter來進行查詢。

query,相反,要計算相關度分數,按照分數進行排序,而且無法cache結果。

在同等查詢結果下,filter的效能一般是要優於query的。

3、explain分析語法

在實際的應用過程中,需要查詢的邏輯一般比較複雜,那當語句冗長的時候,這時候顯然不太可能通過直接執行語句來除錯語法正確與否,這個時候就可以通過explain來驗證語句的正確性。

驗證錯誤語句:

GET /book/_validate/query?explain
{
  "query": {
    "mach": {
      "description": "java程式設計師"
    }
  }
}

返回結果如下,錯誤資訊為沒有名叫mach的query。

{
  "valid" : false,
  "error" : "org.elasticsearch.common.ParsingException: no [query] registered for [mach]"
}

再來看語句正確的情況下

GET /book/_validate/query?explain
{
  "query": {
    "match": {
      "description": "java程式設計師"
    }
  }
}

返回,返回結果還包含對語句的解釋:從description查詢java關鍵詞,從description查詢程式設計師關鍵詞。

{
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "valid" : true,
  "explanations" : [
    {
      "index" : "book",
      "valid" : true,
      "explanation" : "description:java description:程式設計師"
    }
  ]
}

應用場景:

一般用在那種特別複雜龐大的搜尋下,比如你一下子寫了上百行的搜尋,這個時候可以先用validate api去驗證一下,搜尋是否合法。合法以後,explain就像mysql的執行計劃,可以看到搜尋的目標等資訊。

 

相關文章