全部產品
Search
文件中心

OpenSearch:distinct子句

更新時間:Jul 13, 2024

功能說明

打散子句可以在一定程度上保證展示結果的多樣性,以提升使用者體驗。如一次查詢可以查出很多的文檔,但是如果某個使用者的多個文檔分值都比較高,則都排在了前面,導致一頁中所展示的結果幾乎都屬於同一使用者,這樣既不利於結果展示也不利於使用者體驗。對此,打散子句可以對每個使用者的文檔進行抽取,使得每個使用者都有展示文檔的機會。

子句文法

"distinct" : {
     "default": {  
      "dist_key" : "field",
      "dist_count":number,
      "dist_times" : number,
      "dist_filter" : "filter_expression",
      "reserved" : boolean,
      "max_item_count" : number,
      "grade" : []
    },
    "rank": {  
      "dist_key" : "field",
      "dist_count":number,
      "dist_times" : number,
      "dist_filter" : "filter_expression",
      "reserved" : boolean,
      "max_item_count" : number,
      "grade" : []
    },
    "rerank": {
      "dist_key" : "field",
      "dist_count":number,
      "dist_times" : number,
      "dist_filter" : "filter_expression",
      "reserved" : boolean,
      "max_item_count" : number,
      "grade" : []
    }
  }
}

為了保證打散效果,引擎預設在粗排和精排節點分別進行打散。在打散時可以使用相同的打散規則,也可以分別指定不同的打散規則。不同階段打散生效規則如下:

  • 僅指定default規則,粗排和精排都使用default進行打散。

  • 僅指定rank規則,僅粗排階段進行打散。

  • 僅指定rerank規則,僅精排階段進行打散。

  • 同時指定default和rank規則,粗排階段用rank規則打散,精排階段用default規則打散。

  • 同時指定default和rerank規則,粗排階段用default規則打散,精排階段用rerank規則打散。

  • 同時指定rank和rerank規則,粗排階段用rank規則打散,精排階段用rerank規則打散。

  • 同時指定default、rank和rerank規則,粗排階段用rank規則打散,精排階段用rerank規則打散。

  • default、rank、rerank三個規則必須指定一個。

打散規則參數說明

  • dist_key:必選參數,要打散的屬性欄位。

  • dist_count:選擇性參數,一輪抽取的文檔數,預設為1。

  • dist_times:選擇性參數,抽取的輪數,預設為1。

  • dist_filter:選擇性參數,過濾條件,被過濾的doc不參與distinct,只在後面的排序中,這些被過濾的doc將和被distinct出來的第一組doc一起參與排序。預設是全部參與distinct。

  • reserved:選擇性參數,true/false,是否保留抽取之後剩餘的文檔,預設為true。如果為false,為不保留,則搜尋結果的total(總匹配結果數)會不準確。

  • max_item_count:選擇性參數,設定計算distinct時最多保留的doc數目(最多保留數為max(max_item_count, hit))。

    • 為了最終結果翻頁穩定,可以設定為最大可能查詢到的文檔數目(比如每頁10條結果,最多翻頁到100頁,那麼就設定為10*100=1000)。

  • grade:選擇性參數,指定檔位劃分閾值,所有的文檔將根據檔位劃分閾值劃分成若干檔,每個檔位中各自根據distinct參數做distinct,可以不指定該參數,預設是所有文檔都在同一檔。檔位的劃分按照文檔排序時第一維的排序依據的分數進行劃分,兩個檔位閾值之間用 “|” 分開,檔位的個數沒有限制。例如:1、grade:3.0 :表示根據第一維排序依據的分數分成兩檔,(< 3.0)的是第一檔,(>= 3.0) 的是第二檔;2、grade:3.0|5.0 :表示分成三檔,(< 3.0)是第一檔,(>= 3.0,< 5.0)是第二檔,(>= 5.0)是第三檔。檔位的先後順序和第一維排序依據的順序一致,即如果第一維排序依據是降序,則檔位也是降序,反之亦然。

樣本:

"distinct" : {
     "default": {  
      "dist_key" : "company_id",
      "dist_count":2,
      "dist_times" : 10
    }
}
備忘:按照company_id欄位進行打散抽取10輪,每輪取2個結果,抽取後的文檔排在後面

dist_count和dist_times說明

以下範例用來解釋和說明dist_count和dist_times的用法及含義:

假設有6篇文檔,id為主鍵,name為需要做打散的欄位:

doc 1:  id:1  name:a

doc 2:  id:2  name:a

doc 3:  id:3  name:a

doc 4:  id:4  name:b

doc 5:  id:5  name:c

doc 6:  id:6  name:c

case1:

"distinct" : {
     "default": {  
      "dist_key" : "name",
      "dist_count":2,
      "dist_times" : 1
    }
}
#打散結果是:doc1 doc2 doc4 doc5 doc6

case2:

"distinct" : {
     "default": {  
      "dist_key" : "name",
      "dist_count":1,
      "dist_times" : 2
    }
}
#打散結果是:doc1 doc4 doc5 doc2 doc6

case3:

"distinct" : {
     "default": {  
      "dist_key" : "name",
      "dist_count":1,
      "dist_times" : 1
    }
}
#打散結果是:doc1 doc4 doc5

distinct uniq外掛程式

如上面描述,如果reserved=false情況下,會導致搜尋結果中的total及viewtotal不準確,如果使用者需要依賴於這個值進行翻頁或者其他處理,則會有問題。為此,系統提供了distinct uniq的外掛程式來解決在dist_times:1,dist_count:1,reserved:false的情況下的total及viewtotal展示不準確。

在kvpairs中添加duniqfield:field即可。

注意:

  • field必須與distinct子句中的dist_key一致;

  • 該外掛程式僅在在dist_times:1,dist_count:1,reserved:false查詢下起作用,任何參數值有變化都將無效。

  • 出於效能考慮,目前該外掛程式最大支援total值為5000,即使真實搜尋結果數超過5000,也會返回5000。

樣本:

{
  "distinct" : {
    "default": {  
      "dist_key" : "company_id",
      "dist_count":1,
      "dist_times" : 1,
      "reserved" : false
    }
  },
  "kvpairs" : {
    "duniqfield":"company_id"
  }
}

注意事項

  • 在distinct中出現的欄位必須在定義應用結構的時配置為屬性欄位。

  • 不支援array類型,只支援int和literal欄位類型。