Elasticsearch 用 random_score 進行隨機抽樣
Posted on May 9, 2021 in Elasticsearch by Amo Chen ‐ 2 min read
當 Elasticsearch 中存放大量的資料(或稱文件 document)時,一般難以片刻就遍訪每 1 筆資料,如果是為了驗證資料格式,或者需要資料進行實驗,此情況下可選擇用抽樣的方式進行,不僅可利用抽樣的方式預估整個資料庫的情況,也可以有效率地以部分資料進行實驗。
本文記錄如何以 function_score 結合 random_score 進行隨機抽樣。
本文環境
- Elasticsearch 7.10.1
function_score
& random_score
Elasticsearch 預設會將搜尋結果以文件的相關度進行排序,每 1 筆搜尋結果都有 1 個稱為 _score
的欄位,該欄位數值越高代表與搜尋關鍵字的相關度越高,代表越可能是使用者想要的搜尋結果。
但不見得預設的相關度排序方式適合所有類型的資料,因此 Elasticsearch 也提供控制搜尋結果排序的方式,也就是 function_score 。
function_score
提供若干控制相關度的方式(其它方式詳見文件 ),其中 random_score 可用以隨機為每 1 個文件產生 1 個介於 0 到 1 (不包含 1) 的隨機數作為 _score
。
如此一來,我們就能夠利用該函式隨機抽樣,例如以下語法隨機抽樣 1 筆資料:
POST /<index>/_search
{
"query":{
"function_score":{
"random_score":{
}
}
},
"size": 1
}
p.s. 請將 <index>
改為你想要抽樣的 Elasticsearch index 名稱
p.s. 如果需要建立實驗環境,可參考 用 Docker 架設 Elasticsearch 實驗環境 一文
random_score
還可以設定 seed
參數,讓隨機數產生結果可以重現,因此設定 seed
理論上可以每次抽樣到相同的資料,設定 seed
之後仍需要設定 field
參數,告訴 Elasticsearch 以什麼欄位的值產生隨機數值,若不提供的話,預設會以 _id
欄位作為 field
的參數值,但是若以 _id
作為 field
參數值會消耗許多記憶體,若是 production 環境的 Elasticsearch 伺服器,記憶體的異常消耗可能會對服務造成影響,建議可以使用 _seq_no
做為 field
的參數值:
POST /<index>/_search
{
"query":{
"function_score":{
"random_score":{
"seed": 400,
"field": "_seq_no"
}
}
},
"size": 1
}
關於 _seq_no
可以閱讀 Sequence IDs: Coming Soon to an Elasticsearch Cluster Near You 一文,基本上代表每 1 筆資料建立索引時的順序。
值得注意的是,即使設定好 seed
以及 field
仍不能 100% 保證抽樣到相同的資料,因為 Elasticsearch index 仍可能因為資料改變或者進行 merge 等原因造成抽樣結果改變。
更多 radom_score
範例
以下為更多關於 random_score
的範例。
隨機抽樣欄位中含有特定關鍵字的資料
p.s. 請將 <index>
, <field>
與 <keyword>
改成你想要的值
POST /<index>/_search
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"<field>": {
"query": "<keyword>"
}
}
}
]
}
},
"random_score": {}
}
},
"size": 1
}
結合 filter 隨機抽樣欄位中含有特定關鍵字的資料
p.s. 請將 <index>
, <field>
, <keyword>
, <value>
改成你想要的值
POST /<index>/_search
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"<field>": {
"query": "<keyword>"
}
}
}
],
"filter": [
{
"range": {
"<field>": {
"gte": <value>
}
}
}
]
}
},
"random_score": {}
}
},
"size": 1
}
以上為 Elasticsearch 的 random_score
說明。
Happy Coding!
References
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-random