全部產品
Search
文件中心

OpenSearch:distinct子句

更新時間:Jul 13, 2024

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

文法說明

子句文法格式為:dist_key:field,dist_count:1,dist_times:1,reserved:false

參數

類型

必需

取值範圍

預設值

描述

dist_key

string

要打散的欄位

dist_times

int

1

抽取的輪數

dist_count

int

1

一輪抽取的文檔數

reserved

true/false

true/false

true

是否保留抽取之後剩餘的文檔。如果為false,為不保留,則搜尋結果的total(總匹配結果數)會不準確。

update_total_hit

true/false

true/false

false

當reserved為false時,設定update_total_hit為true,則最終total_hit會減去被distinct丟棄的數目(不一定準確),為false則不減。

dist_filter

string

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

grade

float

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

dist_count和dist_times說明

以下範例用來解釋和說明dist_count和dist_times的用法及含義:假設有6篇文檔,id為主鍵,name為需要做打散的欄位:

doc1: id:11 name:a

doc2: id:22 name:a

doc3: id:33 name:a

doc4: id:44 name:b

doc5: id:55 name:c

doc6: id:66 name:c

case1:distinct=dist_key:name,dist_count:2,dist_times:1,reserved:false表示抽取1輪,且一輪抽取2條文檔。打散結果是:doc1 doc2 doc4 doc5 doc6

case2:distinct=dist_key:name,dist_count:1,dist_times:2,reserved:false表示抽取2輪,且每輪抽取1條文檔。打散結果是:doc1 doc4 doc5 doc2 doc6

case3:distinct=dist_key:name,dist_count:1,dist_times:1,reserved:false表示抽取1輪,且一輪抽取1條文檔。打散結果是:doc1 doc4 doc5

注意事項

  1. distinct為非必選子句。

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

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

  4. 不支援指定多個 dist_key 。

  5. 目前排序沒有自動去重的功能,但是可以通過distinct彙總實現去重的結果,例如:要對相同title的文章去重,將title設定為dist_key,抽取1輪,每輪抽取1個文檔即可。

distinct uniq外掛程式

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

注意:

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

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

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

  • 只有添加distinct uniq外掛程式的,真實搜尋結果數超過5000,也會返回5000,沒有添加的不會只統計到5000。

  • 使用該外掛程式並且查詢命中資料量比較大(超百萬級)的情況下,查詢容易逾時。

樣本

  1. 查看create_time(建立時間)在1402301230之後且包含“浙大”的文檔,並按照company_id欄位進行打散抽取10輪,每輪取2個結果,抽取後的文檔排在後面:

    query=default:'浙大'&&filter=create_time>1402301230&&distinct=dist_key:company_id,dist_count:2,dist_times:10
  2. 查看包含“浙大”的文檔,且按照company_id欄位進行打散抽取1輪,每輪取1個結果,抽取後的文檔丟棄(要求返回結果數為丟棄後的):

    query=default:'浙大'&&distinct=dist_key:company_id,dist_count:1,dist_times:1,reserved:false&&kvpairs=duniqfield:company_id