高效篩選elasticsearch嵌套數(shù)組:基于時(shí)間范圍和數(shù)量閾值的精準(zhǔn)查詢
本文介紹如何高效地使用Elasticsearch查詢嵌套數(shù)組,篩選出滿足特定時(shí)間范圍和數(shù)量閾值的記錄。假設(shè)我們的數(shù)據(jù)包含名為change_records的嵌套數(shù)組字段,每個(gè)數(shù)組元素包含change_time字段(時(shí)間戳)。目標(biāo)是查詢change_time在指定時(shí)間范圍內(nèi),且記錄數(shù)量達(dá)到指定閾值的文檔。
之前的腳本查詢方法存在錯(cuò)誤,提示“no field found for [change_records] in mapping with types []”,這是因?yàn)橹苯邮褂胐oc[‘change_records’]訪問嵌套字段的方式不正確。change_records是數(shù)組,需要使用正確的語法訪問其元素。
解決方案:使用script_score查詢結(jié)合Painless腳本自定義評分邏輯。script_score為每個(gè)文檔計(jì)算分?jǐn)?shù),再根據(jù)分?jǐn)?shù)過濾。
以下是一個(gè)修正后的查詢示例:
{ "query": { "script_score": { "query": { "exists": { "field": "change_records" } }, "script": { "source": """ int matches = 0; for (int i = 0; i < doc['change_records'].Length; i++) { long changeTime = doc['change_records'][i]['change_time']; if (changeTime >= params.start && changeTime <= params.end) { matches++; } } return matches >= params.n ? 1 : 0; """, "lang": "painless", "params": { "start": 1627463270000, // 開始時(shí)間戳 "end": 1658999270000, // 結(jié)束時(shí)間戳 "n": 2 // 最小匹配數(shù)量 } } } } }
此查詢首先使用exists查詢確認(rèn)change_records字段存在。然后,script_score中的Painless腳本遍歷change_records數(shù)組,統(tǒng)計(jì)change_time在指定范圍內(nèi)的元素個(gè)數(shù)。如果匹配數(shù)量大于等于params.n,則返回1(匹配);否則返回0。Elasticsearch根據(jù)分?jǐn)?shù)過濾,只返回分?jǐn)?shù)為1的文檔。
關(guān)鍵改進(jìn):
- 正確訪問嵌套字段:使用doc[‘change_records’][i][‘change_time’]。
- 使用length屬性:doc[‘change_records’].length正確獲取數(shù)組長度,避免越界。
- 清晰的評分邏輯:返回1或0,方便理解和調(diào)整。
- 可配置參數(shù):params參數(shù)允許靈活調(diào)整開始時(shí)間戳、結(jié)束時(shí)間戳和最小匹配數(shù)量。
通過此方法,可以高效地篩選Elasticsearch嵌套數(shù)組,滿足在指定時(shí)間范圍內(nèi)且數(shù)量達(dá)到指定閾值的查詢需求。 圖片位置保持不變。