![](/style/images/good.png)
![](/style/images/bad.png)
Elasticsearch.Nest 教程系列 10-3 常用类型:Date math expressions | 日期数字表达...
source link: https://blog.zhuliang.ltd/2020/01/backend/Elasticsearch-Nest-Date-math-expression.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Elasticsearch.Nest 教程系列 10-3 常用类型:Date math expressions | 日期数字表达式
create: 2020-01-23 12:45:01 | update: 2020-01-23 12:15:44 本文总阅读量: 次 | 文章总字数: 1.1k 字 | 阅读约需: 5 分钟
- 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)
- 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html
- 本系列对应的版本环境:[email protected],[email protected],IDE 和开发平台默认为 VS2019,.NET CORE 2.1
在“查询/过滤”的时候支持使用日期类型的数学表达式。表达式以“锚定”日期开始,该日期可以是现在,也可以是以“||”结尾的日期字符串。它后面可以是一个数学表达式,支持 +,- 和 /(四舍五入)。支持的单位有:
- y (year)
- M (month)
- w (week)
- d (day)
- h (hour)
- m (minute)
- s (second)
ES 中的 Date Math。
使用 DateMath 提供的静态方法:
Expect("2020-01-23T00:00:00").WhenSerializing(Nest.DateMath.Anchored(new DateTime(2020,01, 23)));
字符串则会隐式转换为 DateMath
Expect("now").WhenSerializing<Nest.DateMath>("now");
DateMath 对于入参会进行一定程度的容错:
var nonsense = "now||*asdaqwe"; //“*asdaqwe”不是一个有效的时间表达式
Expect(nonsense)
.WhenSerializing<Nest.DateMath>(nonsense)
.AssertSubject(dateMath => ((IDateMath)dateMath)
.Anchor.Match(
d => d.Should().NotBe(default(DateTime)),
s => s.Should().Be(nonsense)
)
);
DateTime 还会隐式转换为简单的日期数学表达式
- 哪怕经过序列化/反序列化后,所得的Anchor 仍将是实际的 DateTime。
var date = new DateTime(2020,1, 23); //将会倍序列化为 "2020-01-23T00:00:00"
//UTC 示例
var utcDate = new DateTime(2020, 1, 23, 0, 0, 0, DateTimeKind.Utc); //将会倍序列化为 "2020-01-23T00:00:00Z"
范围可以链接到简单表达式
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(DateMathTimeUnit.Day));
锚定日期时,需要在锚点和范围之间使用分隔符 “||”。同样,可以链接多个范围
Expect("2020-01-23T00:00:00||+1d-1m").WhenSerializing(
Nest.DateMath.Anchored(new DateTime(2020,1,23))
.Add("1d")
.Subtract(TimeSpan.FromMinutes(1)));
含有小数时间
Elasticsearch中的日期数学表达式不支持小数。
为了在 NEST 中更轻松地使用日期数学,从字符串,TimeSpan 和 double 转换而来的值会将小数部分转换为最大的整数值和单位,四舍五入到最接近的秒数。
Expect("now+1w").WhenSerializing(Nest.DateMath.Now.Add(TimeSpan.FromDays(7)));
Expect("now+1w").WhenSerializing(Nest.DateMath.Now.Add("1w"));
Expect("now+1w").WhenSerializing(Nest.DateMath.Now.Add(604800000));
Expect("now+7d").WhenSerializing(Nest.DateMath.Now.Add("7d"));
Expect("now+30h").WhenSerializing(Nest.DateMath.Now.Add(TimeSpan.FromHours(30)));
Expect("now+30h").WhenSerializing(Nest.DateMath.Now.Add("1.25d"));
Expect("now+90001s").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromHours(25).Add(TimeSpan.FromSeconds(1))));
Expect("now+90000s").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromHours(25).Add(TimeSpan.FromMilliseconds(1))));
Expect("now+1y").WhenSerializing(Nest.DateMath.Now.Add("1y"));
Expect("now+12M").WhenSerializing(Nest.DateMath.Now.Add("12M"));
Expect("now+18M").WhenSerializing(Nest.DateMath.Now.Add("1.5y"));
Expect("now+52w").WhenSerializing(Nest.DateMath.Now.Add(TimeSpan.FromDays(7 * 52)));
可以使用构造函数控制舍入,并传递一个值进行舍入:
Expect("now+2s").WhenSerializing(
Nest.DateMath.Now.Add(new DateMathTime("2.5s", MidpointRounding.ToEven)));
Expect("now+3s").WhenSerializing(
Nest.DateMath.Now.Add(new DateMathTime("2.5s", MidpointRounding.AwayFromZero)));
Expect("now+0s").WhenSerializing(
Nest.DateMath.Now.Add(new DateMathTime(500, MidpointRounding.ToEven)));
Expect("now+1s").WhenSerializing(
Nest.DateMath.Now.Add(new DateMathTime(500, MidpointRounding.AwayFromZero)));
相等性比较
DateMathTime 实现了 equality 和 comparison:
DateMathTime twoSeconds = new DateMathTime(2, DateMathTimeUnit.Second);
DateMathTime twoSecondsFromString = "2s";
DateMathTime twoSecondsFromTimeSpan = TimeSpan.FromSeconds(2);
DateMathTime twoSecondsFromDouble = 2000;
twoSeconds.Should().Be(twoSecondsFromString);
twoSeconds.Should().Be(twoSecondsFromTimeSpan);
twoSeconds.Should().Be(twoSecondsFromDouble);
DateMathTime threeSecondsFromString = "3s";
DateMathTime oneMinuteFromTimeSpan = TimeSpan.FromMinutes(1);
(threeSecondsFromString > twoSecondsFromString).Should().BeTrue();
(oneMinuteFromTimeSpan > threeSecondsFromString).Should().BeTrue();
年份和月份不包含确切值:
- 一年大约365天
- 一个月大约(365/12)天
DateMathTime oneYear = new DateMathTime(1, DateMathTimeUnit.Year);
DateMathTime oneYearFromString = "1y";
DateMathTime twelveMonths = new DateMathTime(12, DateMathTimeUnit.Month);
DateMathTime twelveMonthsFromString = "12M";
oneYear.Should().Be(oneYearFromString);
oneYear.Should().Be(twelveMonths);
twelveMonths.Should().Be(twelveMonthsFromString);
DateMathTime thirteenMonths = new DateMathTime(13, DateMathTimeUnit.Month);
DateMathTime thirteenMonthsFromString = "13M";
DateMathTime fiftyTwoWeeks = "52w";
(oneYear < thirteenMonths).Should().BeTrue();
(oneYear < thirteenMonthsFromString).Should().BeTrue();
(twelveMonths > fiftyTwoWeeks).Should().BeTrue();
(oneYear > fiftyTwoWeeks).Should().BeTrue();
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK