Solr Facet 統計查詢


一)概述

        Facet是solr的高級搜索功能之一,可以給用戶提供更友好的搜索體驗.在搜索關鍵字的同時,能夠按照Facet的字段進行分組並統計。例如下圖所示,你上淘寶,輸入“電腦”進行搜索,就會出現品牌分類,價格范圍等分類,這個就叫Facet。


 

二)Solr Facet類型 

Solr提供了4種類型的Fact

 

[java] view plain copy
 
  1. <lst name="facet_counts">  
  2.   <lst name="facet_queries"/>  
  3.   <lst name="facet_fields"/>  
  4.   <lst name="facet_dates"/>  
  5.   <lst name="facet_ranges"/>  
  6. </lst>  
  1.  
    <lst name="facet_counts">
  2.  
    <lst name="facet_queries"/>
  3.  
    <lst name="facet_fields"/>
  4.  
    <lst name="facet_dates"/>
  5.  
    <lst name="facet_ranges"/>
  6.  
    </lst>

 

    1. facet_queries:代表自定義條件查詢facet,類似數據庫的count函數
    2. facet_fields    :代表根據字段分組查詢,類似數據庫的group by count的組合
    3. facet_dates :根據日期區間分組查詢
    4. facet_ranges:當然了,日期有區間,數字也有,這個就是根據數字分組查詢

三)Solr Facet組件 

         Solr的默認requestHandler已經包含了Facet組件(solr.FacetComponent).如果自定義requestHandler或者對默認的requestHandler自定義組件列表,那么需要將Facet加入到組件列表中去.

 

四)facet query

       Facet Query 用戶自定義條件查詢facet,他提供了非常靈活的Facet.通過facet.query參數,可以對任意字段進行篩選.下面通過實例來闡述。基本上他的用法,都會在我實例中體現出來

例一:日期區間查詢

 

[java] view plain copy
 
  1. &facet=true  
  2. &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]  
  3. &facet.query=date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]  
  1.  
    &facet=true
  2.  
    &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]
  3.  
    &facet.query=date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]

    返回結果如下:

 

 

 

[java] view plain copy
 
  1. <lst name="facet_counts">  
  2.     <lst name="facet_queries">  
  3.         <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int>  
  4.                 <int name="date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]">3</int>  
  5. </lst>  
  6.     <lst name="facet_fields"/>  
  7.     <lst name="facet_dates"/>  
  8. </lst>  
  1.  
    <lst name="facet_counts">
  2.  
    <lst name="facet_queries">
  3.  
    <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int>
  4.  
    <int name="date:[2009-4-1T0:0:0Z TO 2009-5-1T0:0:0Z]">3</int>
  5.  
    </lst>
  6.  
    <lst name="facet_fields"/>
  7.  
    <lst name="facet_dates"/>
  8.  
    </lst>

 

 

例2:數字區間統計

 

[java] view plain copy
 
  1. &facet=on  
  2. &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]  
  3. &facet.query=price:[* TO 5000]  
  1.  
    &facet=on
  2.  
    &facet.query=date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]
  3.  
    &facet.query=price:[* TO 5000]

 返回結果

 

 

[java] view plain copy
 
  1. <lst name="facet_counts">  
  2.     <lst name="facet_queries">  
  3.         <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int>  
  4.                 <int name="price:[* TO 5000]">116</int>  
  5. </lst>  
  6.     <lst name="facet_fields"/>  
  7.     <lst name="facet_dates"/>  
  8. </lst>  
  1.  
    <lst name="facet_counts">
  2.  
    <lst name="facet_queries">
  3.  
    <int name="date:[2009-1-1T0:0:0Z TO 2009-2-1T0:0:0Z]">5</int>
  4.  
    <int name="price:[* TO 5000]">116</int>
  5.  
    </lst>
  6.  
    <lst name="facet_fields"/>
  7.  
    <lst name="facet_dates"/>
  8.  
    </lst>

 例3:自定義條件

 

 

[java] view plain copy
 
  1. &facet=true  
  2. &facet.query=brand:聯想 AND price:1100  
  1.  
    &facet=true
  2.  
    &facet.query=brand:聯想 AND price:1100

 返回結果

 

 

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{  
  3.       "brand:聯想 AND price:1100":1},  
  4.     "facet_fields":{},  
  5.     "facet_dates":{},  
  6.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{
  3.  
    "brand:聯想 AND price:1100":1},
  4.  
    "facet_fields":{},
  5.  
    "facet_dates":{},
  6.  
    "facet_ranges":{}}}

 

 

五)Field Facet

       Facet字段通過在請求中加入facet.field參數加以聲明,如果需要對多個字段進行Facet查詢,那么將該參數聲明多次.這就是類似於數據庫的group by 加上count的功能,非常的靈活。

實例一:最簡單的field facet

 

[java] view plain copy
 
  1. &facet=true  
  2. &facet.field=brand  
  3. &facet.field=price  
  1.  
    &facet=true
  2.  
    &facet.field=brand
  3.  
    &facet.field=price

 返回結果如下

 

 

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{  
  4.       "brand":[  
  5.         "蘋果",4,  
  6.         "聯想",3,  
  7.         "惠普",2],  
  8.       "price":[  
  9.         "1100.0",2,  
  10.         "2200.0",2,  
  11.         "3300.0",2,  
  12.         "1200.0",1,  
  13.         "2100.0",1,  
  14.         "4400.0",1]},  
  15.     "facet_dates":{},  
  16.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{
  4.  
    "brand":[
  5.  
    "蘋果",4,
  6.  
    "聯想",3,
  7.  
    "惠普",2],
  8.  
    "price":[
  9.  
    "1100.0",2,
  10.  
    "2200.0",2,
  11.  
    "3300.0",2,
  12.  
    "1200.0",1,
  13.  
    "2100.0",1,
  14.  
    "4400.0",1]},
  15.  
    "facet_dates":{},
  16.  
    "facet_ranges":{}}}

 從返回結果可以看出各個field字段互不影響;而且可以針對,下面實例會體現

 

 

每個Facet字段設置查詢參數.以下介紹的參數既可以應用於所有的Facet字段,也可以應用於每個單獨的Facet字段.應用於單獨的字段時通過下面語法實現

 

[java] view plain copy
 
  1. f.字段名.參數名=參數值  
f.字段名.參數名=參數值

 例如:將facet.prefix參數應用於brand字段,可以采用如下形式

 

 

[java] view plain copy
 
  1. &facet.field=brand  
  2. &facet.field=price  
  3. &f.brand.facet.prefix=聯  
  1.  
    &facet.field=brand
  2.  
    &facet.field=price
  3.  
    &f.brand.facet.prefix=聯

 返回結果如下:

 

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{  
  4.       "brand":[  
  5.         "聯想",3],  
  6.       "price":[  
  7.         "1100.0",2,  
  8.         "2200.0",2,  
  9.         "3300.0",2,  
  10.         "1200.0",1,  
  11.         "2100.0",1,  
  12.         "4400.0",1]},  
  13.     "facet_dates":{},  
  14.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{
  4.  
    "brand":[
  5.  
    "聯想",3],
  6.  
    "price":[
  7.  
    "1100.0",2,
  8.  
    "2200.0",2,
  9.  
    "3300.0",2,
  10.  
    "1200.0",1,
  11.  
    "2100.0",1,
  12.  
    "4400.0",1]},
  13.  
    "facet_dates":{},
  14.  
    "facet_ranges":{}}}

 

溫馨提示:上面的facet.prefix就是一個參數名,這個很容易誤解為兩個,因為他中間有個點

上面介紹了facet.field參數,下面介紹field fact的其他參數

 

[java] view plain copy
 
  1. 1).facet.prefix  
  2.     表示Facet字段值的前綴.比如facet.field=cpu&facet.prefix=Intel,那么對cpu字段進行Facet查詢,返回的cpu都是以“Intel”開頭的。  
  3. 2).facet.sort  
  4.     表示Facet字段值以哪種順序返回.可接受的值為true(count)|false(index,lex). true(count)表示按照count降序; false(index,lex)表示按照字段值升序(字母,數字的順序)排列.默認情況下為true(count).當facet.limit值為負數時,默認facet.sort= false(index,lex).  
  5. 3).facet.limit  
  6.     限制Facet字段返回的結果條數.默認值為100.如果此值為負數,表示不限制.  
  7. 4).facet.offset  
  8.     返回結果集的偏移量,默認為0.它與facet.limit配合使用可以達到分頁的效果.  
  9. 5).facet.mincount  
  10.     限制了Facet字段值的最小count,默認為0.合理設置該參數可以將用戶的關注點集中在少數比較熱門的領域.相當於group by having  
  11. 6).facet.missing  
  12.     默認為””,如果設置為true或者on,那么將統計那些該Facet字段值為null的記錄.  
  13. 7).facet.method  
  14.     取值為enum或fc,默認為fc.該字段表示了兩種Facet的算法,與執行效率相關.  
  15.     enum適用於字段值比較少的情況,比如字段類型為布爾型,或者字段表示中國的所有省份.Solr會遍歷該字段的所有取值,並從filterCache里為每個值分配一個filter(這里要求solrconfig.xml里對filterCache的設置足夠大).然后計算每個filter與主查詢的交集.  
  16.     fc(表示Field Cache)適用於字段取值比較多,但在每個文檔里出現次數比較少的情況.Solr會遍歷所有的文檔,在每個文檔內搜索Cache內的值,如果找到就將Cache內該值的count加1.  
  17. 8).facet.enum.cache.minDf  
  18.     當facet.method=enum時,此參數其作用,minDf表示minimum document frequency.也就是文檔內出現某個關鍵字的最少次數.該參數默認值為0.設置該參數可以減少filterCache的內存消耗,但會增加總的查詢時間(計算交集的時間增加了).如果設置該值的話,官方文檔建議優先嘗試25-50內的值.  
  1.  
    1).facet.prefix
  2.  
    表示Facet字段值的前綴.比如facet.field=cpu&facet.prefix=Intel,那么對cpu字段進行Facet查詢,返回的cpu都是以“Intel”開頭的。
  3.  
    2).facet.sort
  4.  
    表示Facet字段值以哪種順序返回.可接受的值為true(count)|false(index,lex). true(count)表示按照count降序; false(index,lex)表示按照字段值升序(字母,數字的順序)排列.默認情況下為true(count).當facet.limit值為負數時,默認facet.sort= false(index,lex).
  5.  
    3).facet.limit
  6.  
    限制Facet字段返回的結果條數.默認值為100.如果此值為負數,表示不限制.
  7.  
    4).facet.offset
  8.  
    返回結果集的偏移量,默認為0.它與facet.limit配合使用可以達到分頁的效果.
  9.  
    5).facet.mincount
  10.  
    限制了Facet字段值的最小count,默認為0.合理設置該參數可以將用戶的關注點集中在少數比較熱門的領域.相當於group by having
  11.  
    6).facet.missing
  12.  
    默認為””,如果設置為true或者on,那么將統計那些該Facet字段值為null的記錄.
  13.  
    7).facet.method
  14.  
    取值為enum或fc,默認為fc.該字段表示了兩種Facet的算法,與執行效率相關.
  15.  
    enum適用於字段值比較少的情況,比如字段類型為布爾型,或者字段表示中國的所有省份.Solr會遍歷該字段的所有取值,並從filterCache里為每個值分配一個filter(這里要求solrconfig.xml里對filterCache的設置足夠大).然后計算每個filter與主查詢的交集.
  16.  
    fc(表示Field Cache)適用於字段取值比較多,但在每個文檔里出現次數比較少的情況.Solr會遍歷所有的文檔,在每個文檔內搜索Cache內的值,如果找到就將Cache內該值的count加1.
  17.  
    8).facet.enum.cache.minDf
  18.  
    當facet.method=enum時,此參數其作用,minDf表示minimum document frequency.也就是文檔內出現某個關鍵字的最少次數.該參數默認值為0.設置該參數可以減少filterCache的內存消耗,但會增加總的查詢時間(計算交集的時間增加了).如果設置該值的話,官方文檔建議優先嘗試25-50內的值.

 

 

 

六) Date Facet

       日期類型的字段在文檔中很常見,如商品上市時間,貨物出倉時間,書籍上架時間等等.某些情況下需要針對這些字段進行Facet.不過時間字段的取值有無限性,用戶往往關心的不是某個時間點而是某個時間段內的查詢統計結果. Solr為日期字段提供了更為方便的查詢統計方式.當然,字段的類型必須是DateField(或其子類型)。

        需要注意的是,使用Date Facet時,字段名,起始時間,結束時間,時間間隔這4個參數都必須提供.與Field Facet類似,Date Facet也可以對多個字段進行Facet.並且針對每個字段都可以單獨設置參數。

簡單實例參考

[java] view plain copy
 
  1. &facet.date=birthday  
  2. &facet.date.start=2014-01-00T09:15:00Z  
  3. &facet.date.end=2014-12-00T09:15:00Z  
  4. &facet.date.gap=%2B1MONTH  
  1.  
    &facet.date=birthday
  2.  
    &facet.date.start=2014-01-00T09:15:00Z
  3.  
    &facet.date.end=2014-12-00T09:15:00Z
  4.  
    &facet.date.gap=%2B1MONTH

 返回結果如下所示

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{},  
  4.     "facet_dates":{  
  5.       "birthday":{  
  6.         "2013-12-31T09:15:00Z":0,  
  7.         "2014-01-31T09:15:00Z":0,  
  8.         "2014-02-28T09:15:00Z":0,  
  9.         "2014-03-28T09:15:00Z":0,  
  10.         "2014-04-28T09:15:00Z":0,  
  11.         "2014-05-28T09:15:00Z":0,  
  12.         "2014-06-28T09:15:00Z":0,  
  13.         "2014-07-28T09:15:00Z":0,  
  14.         "2014-08-28T09:15:00Z":0,  
  15.         "2014-09-28T09:15:00Z":1,  
  16.         "2014-10-28T09:15:00Z":5,  
  17.         "2014-11-28T09:15:00Z":3,  
  18.         "gap":"+1MONTH",  
  19.         "start":"2013-12-31T09:15:00Z",  
  20.         "end":"2014-12-28T09:15:00Z"}},  
  21.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{},
  4.  
    "facet_dates":{
  5.  
    "birthday":{
  6.  
    "2013-12-31T09:15:00Z":0,
  7.  
    "2014-01-31T09:15:00Z":0,
  8.  
    "2014-02-28T09:15:00Z":0,
  9.  
    "2014-03-28T09:15:00Z":0,
  10.  
    "2014-04-28T09:15:00Z":0,
  11.  
    "2014-05-28T09:15:00Z":0,
  12.  
    "2014-06-28T09:15:00Z":0,
  13.  
    "2014-07-28T09:15:00Z":0,
  14.  
    "2014-08-28T09:15:00Z":0,
  15.  
    "2014-09-28T09:15:00Z":1,
  16.  
    "2014-10-28T09:15:00Z":5,
  17.  
    "2014-11-28T09:15:00Z":3,
  18.  
    "gap":"+1MONTH",
  19.  
    "start":"2013-12-31T09:15:00Z",
  20.  
    "end":"2014-12-28T09:15:00Z"}},
  21.  
    "facet_ranges":{}}}

  Date Facet參數說明

 

[java] view plain copy
 
  1. 1).facet.date  
  2.     該參數表示需要進行Date Facet的字段名,與facet.field一樣,該參數可以被設置多次,表示對多個字段進行Date Facet.  
  3. 2).facet.date.start  
  4.     起始時間,時間格式為1995-12-31T23:59:59Z  
  5. 3).facet.date.end  
  6.     結束時間.  
  7. 4).facet.date.gap  
  8.     時間間隔.如果start為2009-1-1,end為2010-1-1.gap設置為+1MONTH表示間隔1個月,那么將會把這段時間划分為12個間隔段.  
  9.         注意+因為是特殊字符所以應該用%2B代替.  
  10. 5).facet.date.hardend  
  11.     取值可以為true|false,默認為false.它表示gap迭代到end處采用何種處理.舉例說明start為2009-1-1,end為2009-12-25,gap為+1MONTH,  
  12.     hardend為false的話最后一個時間段為2009-12-1至2010-1-1;  
  13.     hardend為true的話最后一個時間段為2009-12-1至2009-12-25.  
  14. 6).facet.date.other  
  15.     取值范圍為before|after|between|none|all,默認為none,before會對start之前的值做統計,after會對end之后的值做統計,between會對start至end之間所有值做統計.如果hardend為true的話,那么該值就是各個時間段統計值的和.none表示該項禁用.all表示before,after,all都會統計.  
  1.  
    1).facet.date
  2.  
    該參數表示需要進行Date Facet的字段名,與facet.field一樣,該參數可以被設置多次,表示對多個字段進行Date Facet.
  3.  
    2).facet.date.start
  4.  
    起始時間,時間格式為1995-12-31T23:59:59Z
  5.  
    3).facet.date.end
  6.  
    結束時間.
  7.  
    4).facet.date.gap
  8.  
    時間間隔.如果start為2009-1-1,end為2010-1-1.gap設置為+1MONTH表示間隔1個月,那么將會把這段時間划分為12個間隔段.
  9.  
    注意+因為是特殊字符所以應該用%2B代替.
  10.  
    5).facet.date.hardend
  11.  
    取值可以為true|false,默認為false.它表示gap迭代到end處采用何種處理.舉例說明start為2009-1-1,end為2009-12-25,gap為+1MONTH,
  12.  
    hardend為false的話最后一個時間段為2009-12-1至2010-1-1;
  13.  
    hardend為true的話最后一個時間段為2009-12-1至2009-12-25.
  14.  
    6).facet.date.other
  15.  
    取值范圍為before|after|between|none|all,默認為none,before會對start之前的值做統計,after會對end之后的值做統計,between會對start至end之間所有值做統計.如果hardend為true的話,那么該值就是各個時間段統計值的和.none表示該項禁用.all表示before,after,all都會統計.

 

 

 實例參考,演示fact.date.other、跟單獨對某個字段起作用

[java] view plain copy
 
  1. &facet.date=birthday  
  2. &facet.date.start=2014-01-00T09:15:00Z  
  3. &facet.date.end=2014-12-00T09:15:00Z  
  4. &facet.date.gap=%2B1MONTH  
  5. &facet.date.other=all  
  6. &f.birthday.facet.mincount=3 --單獨對某個字段起作用,把統計值小於3的過濾掉  
  1.  
    &facet.date=birthday
  2.  
    &facet.date.start=2014-01-00T09:15:00Z
  3.  
    &facet.date.end=2014-12-00T09:15:00Z
  4.  
    &facet.date.gap=%2B1MONTH
  5.  
    &facet.date.other=all
  6.  
    &f.birthday.facet.mincount=3 --單獨對某個字段起作用,把統計值小於3的過濾掉

 返回結果如下:

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{},  
  4.     "facet_dates":{  
  5.       "birthday":{  
  6.         "2014-10-28T09:15:00Z":5,  
  7.         "2014-11-28T09:15:00Z":3,  
  8.         "gap":"+1MONTH",  
  9.         "start":"2013-12-31T09:15:00Z",  
  10.         "end":"2014-12-28T09:15:00Z",  
  11.         "before":0,  
  12.         "after":0,  
  13.         "between":9}},  
  14.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{},
  4.  
    "facet_dates":{
  5.  
    "birthday":{
  6.  
    "2014-10-28T09:15:00Z":5,
  7.  
    "2014-11-28T09:15:00Z":3,
  8.  
    "gap":"+1MONTH",
  9.  
    "start":"2013-12-31T09:15:00Z",
  10.  
    "end":"2014-12-28T09:15:00Z",
  11.  
    "before":0,
  12.  
    "after":0,
  13.  
    "between":9}},
  14.  
    "facet_ranges":{}}}

 

七)Facet Range

      范圍統計分組統計,跟Date Facet一樣,只是他們定位的字段的類型不同,Data Fact是做日期的分組統計的,而Fact Range是做數字分組統計的,在次強調,是做數字分組統計的,對於字符串,日期是不可以的。

參數跟上面的Date Facet基本一致,如下,就不做解釋了,參考Date Facet的各個參數

[java] view plain copy
 
  1. 1.  facet.range  
  2. 2.  facet.range.start  
  3. 3.  facet.range.end  
  4. 4.  facet.range.gap  
  5. 5.  facet.range.hardend  
  6. 6.  facet.range.other  
  7. 7.  facet.range.include  
  1.  
    1. facet.range
  2.  
    2. facet.range.start
  3.  
    3. facet.range.end
  4.  
    4. facet.range.gap
  5.  
    5. facet.range.hardend
  6.  
    6. facet.range.other
  7.  
    7. facet.range.include

 參考實例

[java] view plain copy
 
  1. &facet.range=price  
  2. &facet.range.start=1000  
  3. &facet.range.end=5000  
  4. &facet.range.gap=1000  
  5. &f.price.facet.mincount=2--單獨對某個字段起作用,把統計值小於2的過濾掉  
  1.  
    &facet.range=price
  2.  
    &facet.range.start=1000
  3.  
    &facet.range.end=5000
  4.  
    &facet.range.gap=1000
  5.  
    &f.price.facet.mincount=2--單獨對某個字段起作用,把統計值小於2的過濾掉

 返回結果如下:

 "facet_counts":{
    "facet_queries":{},
    "facet_fields":{},
    "facet_dates":{},
    "facet_ranges":{
      "price":{
        "counts":[
          "1000.0",3,
          "2000.0",3,
          "3000.0",2],
        "gap":1000.0,
        "start":1000.0,
        "end":5000.0}}}}

 

 

八)key 操作符

上面已經介紹了facet的四類統計,下面介紹一下key,什么是key?

答:key操作符可以為Facet字段取一個別名。哦原來如此簡單!

參考實例:

[java] view plain copy
 
  1. 參數  
  2. &facet=true  
  3. &facet.query=brand:聯想 AND price:1100   
  4. 返回結果  
  5. "facet_counts":{  
  6.     "facet_queries":{  
  7.       "brand:聯想 AND price:1100":1},  
  8.     "facet_fields":{},  
  9.     "facet_dates":{},  
  10.     "facet_ranges":{}}}  
  11. --------------------------------  
  12. 參數  
  13. &facet=true  
  14. &facet.query={!key=聯想}brand:聯想 AND price:1100   
  15. 返回結果  
  16. "facet_counts":{  
  17.     "facet_queries":{  
  18.       "聯想":1},  
  19.     "facet_fields":{},  
  20.     "facet_dates":{},  
  21.     "facet_ranges":{}}}  
  1.  
    參數
  2.  
    &facet=true
  3.  
    &facet.query=brand:聯想 AND price:1100
  4.  
    返回結果
  5.  
    "facet_counts":{
  6.  
    "facet_queries":{
  7.  
    "brand:聯想 AND price:1100":1},
  8.  
    "facet_fields":{},
  9.  
    "facet_dates":{},
  10.  
    "facet_ranges":{}}}
  11.  
    --------------------------------
  12.  
    參數
  13.  
    &facet=true
  14.  
    &facet.query={!key=聯想}brand:聯想 AND price:1100
  15.  
    返回結果
  16.  
    "facet_counts":{
  17.  
    "facet_queries":{
  18.  
    "聯想":1},
  19.  
    "facet_fields":{},
  20.  
    "facet_dates":{},
  21.  
    "facet_ranges":{}}}

 從上面可以看出來,這樣可以讓字段名統一起來,方便我們拿到請求數據后,封裝成自己的對象

 

九)tag操作符和ex操作符

這個也非常的重要,看下應用場景,當查詢使用filter query 或者q的時候,如果filter query的字段正好是Facet字段,那么查詢結果往往被限制在某一個值內.

參考實例

[java] view plain copy
 
  1. &fq=price:[1000 TO 2000]  
  2. &facet.field=price  
  1.  
    &fq=price:[1000 TO 2000]
  2.  
    &facet.field=price

 返回結果

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{  
  4.       "price":[  
  5.         "1100.0",2,  
  6.         "1200.0",1,  
  7.         "2100.0",0,  
  8.         "2200.0",0,  
  9.         "3300.0",0,  
  10.         "4400.0",0]},  
  11.     "facet_dates":{},  
  12.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{
  4.  
    "price":[
  5.  
    "1100.0",2,
  6.  
    "1200.0",1,
  7.  
    "2100.0",0,
  8.  
    "2200.0",0,
  9.  
    "3300.0",0,
  10.  
    "4400.0",0]},
  11.  
    "facet_dates":{},
  12.  
    "facet_ranges":{}}}

       從返回的結果可以看到fq將查詢的結果集限制在了price 在1000 至 2000之間,其他范圍的統計沒有實際意義。

    有些時候,用戶希望把結果限制在某一個范圍以內,又希望查看該范圍外的概況,像上述情況,用戶想把結果限制在(price)1000~2000之間,但是又想查看其他價格區間有多少產品。這個時候需要用到tag和ex操作符.tag就是把一個filter標記起來,ex(exclude)是在Facet的時候把標記過的filter排除在外.

參考實例

 

[java] view plain copy
 
  1. &fq={!tag=aa}price:[1000 TO 2000]  
  2. &facet.field={!ex=aa}price  
  1.  
    &fq={!tag=aa}price:[1000 TO 2000]
  2.  
    &facet.field={!ex=aa}price

 返回結果

 

[java] view plain copy
 
  1. "facet_counts":{  
  2.     "facet_queries":{},  
  3.     "facet_fields":{  
  4.       "price":[  
  5.         "1100.0",2,  
  6.         "2200.0",2,  
  7.         "3300.0",2,  
  8.         "1200.0",1,  
  9.         "2100.0",1,  
  10.         "4400.0",1]},  
  11.     "facet_dates":{},  
  12.     "facet_ranges":{}}}  
  1.  
    "facet_counts":{
  2.  
    "facet_queries":{},
  3.  
    "facet_fields":{
  4.  
    "price":[
  5.  
    "1100.0",2,
  6.  
    "2200.0",2,
  7.  
    "3300.0",2,
  8.  
    "1200.0",1,
  9.  
    "2100.0",1,
  10.  
    "4400.0",1]},
  11.  
    "facet_dates":{},
  12.  
    "facet_ranges":{}}}

 這樣其它價格區間的統計信息就有意義了.

 

 

十)Facet 字段設計

一、Facet字段的要求

        Facet的字段必須被索引.一般來說該字段無需分詞,無需存儲.

        無需分詞是因為該字段的值代表了一個整體概念,如電腦的品牌”聯想”代表了一個整體概念,如果拆成”聯”,”想”兩個字都不具有實際意義.另外該字段的值無需進行大小寫轉換等處理,保持其原貌即可.

        無需存儲是因為一般而言用戶所關心的並不是該字段的具體值,而是作為對查詢結果進行分組的一種手段,用戶一般會沿着這個分組進一步深入搜索.

 

二、特殊情況

          對於一般查詢而言,分詞和存儲都是必要的.比如CPU類型“Intel 酷睿2雙核 P7570”,拆分成“Intel”,“酷睿”,“P7570”這樣一些關鍵字並分別索引,可能提供更好的搜索體驗.但是如果將CPU作為Facet字段,最好不進行分詞.這樣就造成了矛盾,解決方法為,將CPU字段設置為不分詞不存儲,然后建立另外一個字段為它的COPY,對這個COPY的字段進行分詞和存儲.

[java] view plain copy
 
  1. <types>  
  2.     <fieldType name="string" class="solr.StrField" omitNorms="true"/>  
  3.     <fieldType name="tokened" class="solr.TextField" >  
  4.         <analyzer>  
  5.         ……  
  6.         </analyzer>  
  7.     </fieldType>  
  8. </types>  
  9. <fields>  
  10.     <field name="cpu" type="string" indexed="true" stored="false"/>  
  11.     <field name="cpuCopy” type=" tokened" indexed="true" stored="true"/>  
  12. </fields>  
  13. <copyField source="cpu" dest="cpuCopy"/>  
  1.  
    <types>
  2.  
    <fieldType name="string" class="solr.StrField" omitNorms="true"/>
  3.  
    <fieldType name="tokened" class="solr.TextField" >
  4.  
    <analyzer>
  5.  
    ……
  6.  
    </analyzer>
  7.  
    </fieldType>
  8.  
    </types>
  9.  
    <fields>
  10.  
    <field name="cpu" type="string" indexed="true" stored="false"/>
  11.  
    <field name="cpuCopy” type=" tokened" indexed="true" stored="true"/>
  12.  
    </fields>
  13.  
    <copyField source="cpu" dest="cpuCopy"/>

 

 

 官網API:  http://wiki.apache.org/solr/SimpleFacetParameters 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM