solr高級查詢——facet分面

1.簡述

1.1 概念

分面搜索也稱爲分面瀏覽,他允許用戶在執行搜索時,根據文檔的一個或者多個方面(即分面)對搜索結果進行細分。用戶通過選擇不同的過濾器來探索搜索結果。

1.2 應用場景

在搜索求職網站時,我們希望對搜索結果按照城市、工作類別、行業甚至是公司名稱等選項進行篩選。一般來說,這些過濾選項不僅展示了每個分面的可用值,而且統計了每個分面值匹配到的搜索結果數。由於屏幕只能爲每個分面顯示有限數量的值,搜索引擎通常會根據熱門程度(文檔匹配最多的)對分面值進行排序。讓用戶無需查看每個搜索結果,就可以快速的搜索結果的整體情況。

1.3 功能

solr的分面功能將動態元數據隨搜索結果一起返回。分面最基本的形式是展示字段中的每一個唯一值和其對匹配的文檔出現的次數(注意:不是匹配的文檔數量而是匹配的文檔出現次數),這個字段來自文檔的共享屬性,例如:類目列表。

solr提供了許多高級分面功能,包括基於函數、值區間以及任意查詢的搜索結果分面。solr還支持層級分面多維分面多選分面,其中多選分面可以對那些以及從搜索結果中過濾掉的文檔進行分面計數。

2.搜索結果預覽

分面搜索一般有兩個步驟組成:分面的計算與顯示,即“分面返回”,有時簡稱爲分面;用戶選擇一個或者多個分面值,對搜索結果進行過濾,即“分面選擇“或者”分面過濾“

假設對一組參觀文檔進行搜索,你可能希望在用戶界面放置一些分面來作爲導航元素,如下圖,當查詢”hamburger“時返回的結果:

圖片地址

如上圖,每個類別(餐廳類型、州、價格區間及城市)都被視爲一個分面。分面可以看成是對搜索結果的一個信息切片。這個界面類似於我們在購物網站搜索某一件商品後,然後根據商品的各種屬性進行進一步的篩選。

3.字段分面

字段分面是最常見的分面形式。執行搜索時,根據查詢請求返回特定字段中找到唯一值以及找到文檔數。字段分麪包括:單值分面多值分面 。其中單值分面中每個唯一值都會被檢視,並返回每個值對應的文檔數,由於每個文檔只需要一個值,因此此值的統計數等同於文檔總數。多值分面中,多個標籤可能對應同一個文檔,因此大多數文檔被不止一個分面值計數過。

對於多值分面,Solr開發者創建了一個單獨的字段,在該字段中放入特定內容的副本,該字段僅用於分面目的,這樣原始文本就能夠以分面的形式保留。

3.1 字段分面參數

Solr參數可能取值說明
facettrue,false對當前搜索是否啓用分面
facet.field任意索引字段名稱確定對那個字段進行分面,可多次指定
facet.sortindex,count排序方式:根據最大出現次數(count)或者索引(index)的詞典序排序
facet.limit整數>=-1返回多少個唯一分面值
facet.mincount整數>=0在分面返回之前設置必須出現最少文檔數,默認爲1.
facet.methodenum,fc,fcsenum方法循環遍歷索引中所有詞項,計算這些詞項與查詢的交集,fc(字段緩存)方法對與查詢匹配的文檔進行循環,在這些文檔中找到詞項,fc是除了布爾值之外的默認方法。fcs方法爲單值字符串調用每個片段緩存。
facet.enum.cache.minDf整數>=0在filterCache用於詞項之前,指定與蓋茨匹配的最小文檔數
facet.prefix任意字符串指定查詢到詞項的前綴
facet.missingtrue,false是否返回不包含分面字段的文檔計數
facet.offset整數>=0通過分面值進行分頁。offset指定跳過最開始的幾個值,昨晚後面分面的替代
facet.threads整數當執行多個字段分面時指定的線程數。默認是0,負數代表爲每個字段生成一個線程

其中,可以基於字段進行指定的有:facet.limit,facet.mincount,facet.method,facet.enum.cache.minDf,使用格式爲: f..= eg:

requestUrl:

http://192.168.10.125:8983/solr/techproducts/select?q=*:*&
facet=true&                // 開啓facet
facet.limit=6&             // 默認所有facet展示六條數據
facet.field=weight&        // facet字段爲weight
f.weight.facet.limit=4&    // 指定weight字段只顯示4條
f.weight.facet.sort=index& // 指定weight字段爲字典序排序
facet.field=cat&            
f.cat.facet.mincount=2     // 最少統計數爲2

response:

"facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "weight":[            
        "2.0",1,
        "4.0",1,
        "5.5",1,
        "6.4",1],
      "cat":[
        "electronics",12,
        "currency",4,
        "memory",3,
        "connector",2,
        "graphics card",2,
        "hard drive",2]},
        "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

如結果所示:weight排序方式爲字典序,cat排序方式爲默認的count,即按照統計數量大小降序;weight展示了4條記錄,cat未特殊指定數量,展示了默認的6條數據;cat指定最少統計數爲2,weight未指定所以也展示出了爲1的。

4. 查詢分面

將某一個字段的值分爲多個區間,查詢每個區間對應的數量。例如,我們想知道商品在區間[,200]、[200,400]、[400,600]、[600,]中,每個區間對應的數量,則可以使用查詢分面。格式爲:facet.query=field:[start+TO+end],其中"["代表閉區間,"{"代表開區間,"+"代表空格,注意"TO"必須爲大寫。

http://192.168.10.125:8983/solr/techproducts/select?q=*:*&rows=0&facet=true&
facet.query=price:[*+TO+200}&
facet.query=price:[200+TO+400}&
facet.query=price:[400+TO+600}&
facet.query=price:[600+TO+*]
 "facet_counts":{
    "facet_queries":{
      "price:[* TO 200}":9,
      "price:[200 TO 400}":4,
      "price:[400 TO 600}":1,
      "price:[600 TO *]":2},
    "facet_fields":{},
    "facet_ranges":{},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

5.區間分面

區間分面將數值和日期字段分成一些區間,以便於solr返回各個區間以及他們包含的文檔數。創建多個不同的查詢分面來表示多個區間值的做法可以通過區間分面進行替代。

對上面的例子可通過以下方式實現:

http://192.168.10.125:8983/solr/techproducts/select?q=*:*&rows=0&facet=true&
facet.range=price&              // 分區字段
f.price.facet.range.start=0.0&  // 分區起始值
f.price.facet.range.end=1000.0& // 分區結束值
f.price.facet.range.gap=200     // 分區步長

可得到同樣的統計結果

  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{},
    "facet_ranges":{
      "price":{
        "counts":[
          "0.0",9,
          "200.0",4,
          "400.0",1,
          "600.0",1,
          "800.0",0],
        "gap":200.0,
        "start":0.0,
        "end":1000.0}},
    "facet_intervals":{},
    "facet_heatmaps":{}}}

6.Pivot(Decision Tree)Faceting 決策樹分面

通過pivot關鍵字定義樹狀結構的分面結果,在一個分面結果中可以包含另一個分面結果

http://localhost:8983/solr/techproducts/select?q=*:*&
facet.pivot=cat,popularity,inStock&
facet.pivot=popularity,cat&
facet=true&
facet.field=cat&
facet.limit=5&
rows=0&
facet.pivot.mincount=2

分面結果:

{  "facet_counts":{
    "facet_queries":{},
    "facet_fields":{
      "cat":[
        "electronics",14,
        "currency",4,
        "memory",3,
        "connector",2,
        "graphics card",2]},
    "facet_dates":{},
    "facet_ranges":{},
    "facet_pivot":{
      "cat,popularity,inStock":[{
          "field":"cat",
          "value":"electronics",
          "count":14,
          "pivot":[{
              "field":"popularity",
              "value":6,
              "count":5,
              "pivot":[{
                  "field":"inStock",
                  "value":true,
                  "count":5}]}]
}]}}}

7.其他

  1. 可在分面值查詢請求上添加過濾器,例如&fq=price:[*+TO100] ,將過濾掉對[0,100]的統計.
  2. 多值過濾時需要使用雙引號,例如fq=city:"china beijing",如果字符串中有特殊符號需要進行轉意,例如:fq=name:"the \"in\" crowd" .
  3. 通過key關鍵字給分面字段重命名,例如facet.query={!key="兩百以下"}price :[*+TO+200],則facet_query中的顯示結果將由"price:[* TO 200}":9,變爲"price:[兩百以下}":9,
  4. 通過tag和ex標記忽略過濾器。用tag定義一個過濾器fq={!tag="tag1"}state:California,定一個了一個隊state字段的過濾器,並命名爲tag1,然後在facet的field定義時使用tag標籤facet.field={!ex=tag1}state,這樣state分面就會忽略標記爲tag1的過濾器,也就是這個過濾器對state字段不進行過濾。

參考

http://lucene.apache.org/solr/guide/7_0/faceting.html#pivot-decision-tree-faceting

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章