Date math expressions Version: 5.x 英文原文地址: "Date math expressions" query/filter 中涉及到日期類型時(如: 參數),Elasticsearch 允許我們使用日期數學表達式。 表達式由一個 "anchor" (錨點)日期開頭 ...
Date math expressions
Version: 5.x
英文原文地址:Date math expressions
query/filter 中涉及到日期類型時(如:timeout
參數),Elasticsearch 允許我們使用日期數學表達式。
表達式由一個 "anchor" (錨點)日期開頭,這個錨點可以是 now
或者其他可用的以 ||
結尾的日期格式字元串。錨點之後可以跟著一個數學表達式,支持 +
, -
和 /
(舍入取整)。可用的單位有:
y
(year) 年M
(month) 月w
(week) 周d
(day) 日h
(hour) 時m
(minute) 分s
(second) 秒
單純的一個整數表示以毫秒為單位的時間,2d
表示 2 天。
更多信息請參閱 Elasticsearch 官方文檔中關於 Date Math 的說明。
說明:”錨點||數學表達式“ 所描述的其實就是一個參考日期 + 一個偏移時間。舉個慄子:
2018-01-01||+1d
表達的是 2018年1月2日
Simple expressions
你可以使用 DateMath
的靜態方法創建一個簡單的表達式
Expect("now").WhenSerializing(Nest.DateMath.Now);
Expect("2015-05-05T00:00:00").WhenSerializing(Nest.DateMath.Anchored(new DateTime(2015,05, 05)));
字元串會隱式轉換成 DateMath
Expect("now").WhenSerializing<Nest.DateMath>("now");
但是不會智能過濾錯誤的數學表達式
var nonsense = "now||*asdaqwe";
上面這個字元串轉換成 DateMath
後會被當作一個錨點日期(沒有數學表達式)
Expect(nonsense).WhenSerializing<Nest.DateMath>(nonsense)
.Result(dateMath => ((IDateMath)dateMath)
.Anchor.Match(
d => d.Should().NotBe(default(DateTime)),
s => s.Should().Be(nonsense)
)
);
DateTime
也可以隱式轉換成簡單的日期數學表達式;生成的錨點是一個實際的 DateTime
,即使經過了往返過程中的序列化/反序列化
var date = new DateTime(2015, 05, 05);
Expect("2015-05-05T00:00:00").WhenSerializing<Nest.DateMath>(date)
.Result(dateMath => ((IDateMath)dateMath)
.Anchor.Match(
d => d.Should().Be(date),
s => s.Should().BeNull()
)
);
Complex expressions
可以將範圍鏈接到簡單表達式後面
Expect("now+1d").WhenSerializing(Nest.DateMath.Now.Add("1d"));
可以鏈接多種操作
Expect("now+1d-1m").WhenSerializing(
Nest.DateMath.Now.Add("1d").Subtract(TimeSpan.FromMinutes(1)));
舍入值可以鏈接到表達式的末尾,在此之後不能追加其他範圍
Expect("now+1d-1m/d").WhenSerializing(
Nest.DateMath.Now.Add("1d")
.Subtract(TimeSpan.FromMinutes(1))
.RoundTo(Nest.TimeUnit.Day));
當設置一個錨點日期(參照日期),需要在定位點和範圍之間插入一個分割符 ||
(自動地)。同樣的,後面可以追加多個範圍
Expect("2015-05-05T00:00:00||+1d-1m").WhenSerializing(
Nest.DateMath.Anchored(new DateTime(2015,05,05))
.Add("1d")
.Subtract(TimeSpan.FromMinutes(1)));
Fractional times
DateMath
表達式不支持小數,所以會選擇一個可以將表達式轉換成整數的最大的單位
Expect("now+25h")
.WhenSerializing(Nest.DateMath.Now.Add(TimeSpan.FromHours(25)))
.WhenSerializing(Nest.DateMath.Now.Add(90000000))
.WhenSerializing(Nest.DateMath.Now.Add(new Time(25, Nest.TimeUnit.Hour)))
.WhenSerializing(Nest.DateMath.Now.Add("25h"));
Expect("now+90001s").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromHours(25).Add(TimeSpan.FromSeconds(1))));
Expect("now+90000001ms").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromHours(25).Add(TimeSpan.FromMilliseconds(1))));
Expect("now+1y")
.WhenSerializing(Nest.DateMath.Now.Add("1y"))
.WhenSerializing(Nest.DateMath.Now.Add(new Time(1, Nest.TimeUnit.Year)));
Expect("now+6M")
.WhenSerializing(Nest.DateMath.Now.Add("6M"))
.WhenSerializing(Nest.DateMath.Now.Add("0.5y"))
.WhenSerializing(Nest.DateMath.Now.Add(new Time(0.5, Nest.TimeUnit.Year)))
.WhenSerializing(Nest.DateMath.Now.Add(new Time(6, Nest.TimeUnit.Month)));
Expect("now+364d")
.WhenSerializing(Nest.DateMath.Now.Add(TimeSpan.FromDays(7 * 52)));
Expect("now+52w")
.WhenSerializing(Nest.DateMath.Now.Add(new Time("52w")))
.WhenSerializing(Nest.DateMath.Now.Add(new Time(52, Nest.TimeUnit.Week)));