Elasticsearch 查詢結果分組統計,聚合檢索(group by stats)

AR414發表於2021-03-05

前言

在使用Elasticsearch做搜尋的時候,經常會碰到需要將搜尋的結果分好類別,每個只取指定數量給到前端,舉個例子:鬥魚直播平臺搜尋

Elasticsearch 查詢結果分組統計,聚合檢索(group by stats)

假設搜尋結果就分三個組:相關主播, 相關視訊, 相關UP主
再假設所有組的資料都儲存在同一個索引

假設索引結構

data: 綜合搜尋展示的簡要資料
content: 搜尋關鍵詞集合, 例如: “盧本偉,55開,世界第一小魚人,英雄聯盟”
type: 類別, 例如: 主播,視訊,UP主
weight: 權重

{
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "data": {
        "type": "object"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "type": {
        "type": "keyword"
      },
      "weight": {
        "type": "keyword"
      }
    }
  }
}

查詢結果分組統計

  1. 將結果按類別分組,每個組都按權重進行倒序,每組只展示前6個,只保留data資料項

    {
    "size": 0,
    "query": {
     "match_phrase": {
       "content": "大神"
     }
    },
    "aggs": {
     "ret": {
       "terms": {
         "field": "type",
         "size": "3"
       },
       "aggs": {
         "type": {
           "terms": {
             "field": "type",
             "size": 3
           },
           "aggs": {
             "top": {
               "top_hits": {
                 "sort": [
                   {
                     "weight": {
                       "order": "desc"
                     }
                   }
                 ],
                 "_source": [
                   "data"
                 ],
                 "size": 6
               }
             }
           }
         }
       }
     }
    }
    }
  2. 如果每個類別都需要單獨定製引數,比如主播按權重倒序, 視訊按釋出時間倒序

    {
    "size": 0,
    "query": {
     "match_phrase": {
       "content": "大神"
     }
    },
    "aggs": {
     "anchor": { //主播
       "filter": {
         "bool": {
           "must": {
             "term": {
               "type": "1"
             }
           }
         }
       },
       "aggs": {
         "type": {
           "terms": {
             "field": "type",
             "size": 1
           },
           "aggs": {
             "top": {
               "top_hits": {
                 "sort": [
                   {
                     "weight": {
                       "order": "desc"
                     }
                   }
                 ],
                 "_source": [
                   "data"
                 ],
                 "size": 6
               }
             }
           }
         }
       }
     },
     "video": { //視訊
       "filter": {
         "bool": {
           "must": {
             "term": {
               "type": "2"
             }
           }
         }
       },
       "aggs": {
         "type": {
           "terms": {
             "field": "type",
             "size": 1
           },
           "aggs": {
             "top": {
               "top_hits": {
                 "sort": [
                   {
                     "create_time": {
                       "order": "desc"
                     }
                   }
                 ],
                 "_source": [
                   "data"
                 ],
                 "size": 6
               }
             }
           }
         }
       }
     }
    }
    }

結語

Elasticsearch的功能非常強大,個人偏向於能在Elasticsearch上完成的事不會放在php程式碼中處理, 如果你有更便捷更好的寫法歡迎分享

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章