ES 22 - Elasticsearch中如何進行日期(數值)范圍查詢


1 范圍查詢的符號

符號 含義
gte greater-than or equal to, 大於或等於
gt greater-than, 大於
lte less-than or equal to, 小於或等於
lt less-than, 小於

2 數值范圍查詢

需求: 查詢商品中40 <= price <= 80的文檔:

GET book_shop/_search
{
    "query": {
        "range": {
            "price": {
                "gte": 40,
                "lte": 80,
                "boost": 2.0	// 設置得分的權重值(提升值), 默認是1.0
            }
        }
    }
}

3 時間范圍查詢

3.1 簡單查詢示例

需求: 查詢網站中最近一天發布的博客:

GET website/_search
{
    "query": {
        "range": {
            "post_date": {
            	"gte": "now-1d/d",	// 當前時間的上一天, 四舍五入到最近的一天
            	"lt":  "now/d"		// 當前時間, 四舍五入到最近的一天
        	}
        }
    }
}

3.2 關於時間的數學表達式(date-math)

Elasticsearch中時間可以表示為now, 也就是系統當前時間, 也可以是以||結尾的日期字符串表示.

在日期之后, 可以選擇一個或多個數學表達式:

  • +1h —— 加1小時;
  • -1d —— 減1天;
  • /d —— 四舍五入到最近的一天.

下面是Elasticsearch支持數學表達式的時間單位:

表達式 含義 表達式 含義
y M
w 星期 d
h 小時 H 小時
m 分鍾 s

說明: 假設系統當前時間now = 2018-10-01 12:00:00 :

  • now+1h: now的毫秒值 + 1小時, 結果是: 2018-10-01 13:00:00.
  • now-1h: now的毫秒值 - 1小時, 結果是: 2018-10-01 11:00:00.
  • now-1h/d: now的毫秒值 - 1小時, 然后四舍五入到最近的一天的起始, 結果是: 2018-10-01 00:00:00.
  • 2018.10.01||+1M/d: 2018-10-01的毫秒值 + 1月, 再四舍五入到最近一天的起始, 結果是: 2018-11-01 00:00:00.

3.3 關於時間的四舍五入

對日期中的日、月、小時等 進行四舍五入時, 取決於范圍的結尾是包含(include)還是排除(exclude).

向上舍入: 移動到舍入范圍的最后一毫秒;

向下舍入: 一定到舍入范圍的第一毫秒.

舉例說明:

"gt": "2018-12-18||/M" —— 大於日期, 需要向上舍入, 結果是2018-12-31T23:59:59.999, 也就是不包含整個12月.

"gte": "2018-12-18||/M" —— 大於或等於日期, 需要向下舍入, 結果是 2018-12-01, 也就是包含整個12月.

"lt": "2018-12-18||/M" —— 小於日期, 需要向上舍入, 結果是2018-12-01, 也就是不包含整個12月.

"lte": "2018-12-18||/M" —— 小於或等於日期, 需要向下舍入, 結果是2018-12-31T23:59:59.999, 也就是包含整個12月.


4 日期格式化范圍查詢(format)

格式化日期查詢時, 將默認使用日期field中指定的格式進行解析, 當然也可以通過format參數來覆蓋默認配置.

示例:

GET website/_search
{
    "query": {
        "range": {
            "post_date": {
                "gte": "2/1/2018", 
                "lte": "2019",
                "format": "dd/MM/yyyy||yyyy"
            }
        }
    }
}

注意: 如果日期中缺失了部分年、月、日, 缺失的部分將被填充為unix系統的初始值, 也就是1970年1月1日.

比如, 將dd指定為format, 像"gte": 10將轉換為1970-01-10T00:00:00.000Z.


5 時區范圍查詢(time_zone)

如果日期field的格式允許, 也可以通過在日期值本身中指定時區, 從而將日期從另一個時區的時間轉換為UTC時間, 或者為其指定特定的time_zone參數.

示例:

GET website/_search
{
    "query": {
        "range": {
            "post_date": {
                "gte": "2018-01-01 00:00:00",
                "lte": "now",
                "format": "yyyy-MM-dd hh:mm:ss",
                "time_zone": "+1:00"
            }
        }
    }
}

ES中的日期類型必須按照UTC時間格式存儲, 所以, 上述的2018-01-01 00:00:00將被轉換為2017-12-31T23:00:00 UTC.

另外需要注意的是, now是不受time_zone影響的.

參考資料

Elasticsearch官方文檔 - Range Query

版權聲明

作者: 馬瘦風(https://healchow.com)

出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)

感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜

本文版權歸博主所有, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文鏈接], 否則博主保留追究相關人員法律責任的權利.


免責聲明!

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



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