Elasticsearch——Filter search results

741439599發表於2021-11-17

可以使用兩種方法篩選搜尋結果:

  • 使用帶有filter子句的boolean查詢。搜尋請求(search requests)對搜尋命中(search hits)和聚合(aggregations)應用布林過濾器(boolean filters)。
  • 使用搜尋API的post_filter引數。搜尋請求僅對search hits應用post filters,而不是聚合。我們可以使用post filter根據更廣泛的結果集計算聚合,然後進一步縮小結果範圍。

Post filter

使用post_filter引數篩選搜尋結果時,計算聚合後將過濾search hits。post filter對聚合結果沒有影響。

例如,我們銷售的襯衫具有以下屬性:

PUT /shirts
{
  "mappings": {
    "properties": {
      "brand": { "type": "keyword"},
      "color": { "type": "keyword"},
      "model": { "type": "keyword"}
    }
  }
}

PUT /shirts/_doc/1?refresh
{
  "brand": "gucci",
  "color": "red",
  "model": "slim"
}

假設使用者指定了兩個篩選器:
color:red,brand:gucci我們只想在搜尋結果中向他們展示gucci製造的紅衫。通常情況下,我們可以通過bool query執行此操作:

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  }
}

但是,我們還希望使用分面導航來顯示使用者可以單擊的其他選項的列表。也許我們有一個模型欄位,允許使用者將搜尋結果限制為red gucci T恤或連衣裙。

這可以通過 terms aggregation實現:

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  },
  "aggs": {
    "models": {
      "terms": { "field": "model" } 
    }
  }
}

但也許我們也想告訴使用者有多少其他顏色的gucci襯衫。如果我們只是在“color”欄位上新增一個terms aggregation,我們將只返回紅色,因為我們的查詢只返回Gucci的紅衫。

相反,我們希望在聚合期間包括所有顏色的襯衫,然後僅對搜尋結果應用colors filter。這就是post_filter的用途:

GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": { "brand": "gucci" }1}
    }
  },
  "aggs": {
    "colors": {
      "terms": { "field": "color" }2},
    "color_red": {
      "filter": {
        "term": { "color": "red" }3},
      "aggs": {
        "models": {
          "terms": { "field": "model" }3}
      }
    }
  },
  "post_filter": {4"term": { "color": "red" }
  }
}
  1. 現在,主查詢將按Gucci查詢所有襯衫,而不考慮顏色。
  2. colors agg返回Gucci襯衫的流行顏色。
  3. color_red agg將模型子聚合限制為紅色Gucci襯衫。
  4. 最後,post_filter從搜尋點選(search hits)中刪除除紅色以外的其他顏色。
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章