常见类型
NEST有许多类型用于使用Elasticsearch规范
时间单位
距离单位
日期数学表达式
时间单位
无论何时需要指定持续时间,例如对于超时参数,持续时间可以指定为表示时间(毫秒)的整数,或者作为2d
的时间值指定2天。
NEST使用Time
类型来强制键入,并且有几种方法来构造一个。
构造函数
构建Time
的最直接的方法是通过其构造函数
var unitString = new Time("2d");
var unitComposed = new Time(2, Nest.TimeUnit.Day);
var unitTimeSpan = new Time(TimeSpan.FromDays(2));
var unitMilliseconds = new Time(1000 * 60 * 60 * 24 * 2);
当序列化时间构建时从
一个字符串
毫秒(作为double)
因素和间隔的组成
TimeSpan
表达式将被序列化为由因子和间隔组成的时间单位字符串如2d
Expect("2d")
.WhenSerializing(unitString)
.WhenSerializing(unitComposed)
.WhenSerializing(unitTimeSpan)
.WhenSerializing(unitMilliseconds);
即使不使用需要一个double的构造函数,也会计算Time
上的Milliseconds
属性
unitMilliseconds.Milliseconds.Should().Be(1000*60*60*24*2);
unitComposed.Milliseconds.Should().Be(1000*60*60*24*2);
unitTimeSpan.Milliseconds.Should().Be(1000*60*60*24*2);
unitString.Milliseconds.Should().Be(1000*60*60*24*2);
隐式转换
或者使用构造函数,string
,TimeSpan
和double
可以隐式转换为Time
Time oneAndHalfYear = "1.5y";
Time twoWeeks = TimeSpan.FromDays(14);
Time twoDays = 1000*60*60*24*2;
Expect("1.5y").WhenSerializing(oneAndHalfYear);
Expect("2w").WhenSerializing(twoWeeks);
Expect("2d").WhenSerializing(twoDays);
Time oneAndHalfYear = "1.5y";
Time twoWeeks = TimeSpan.FromDays(14);
Time twoDays = 1000*60*60*24*2;
即使值不通过,也会计算毫秒数…
twoWeeks.Milliseconds.Should().BeGreaterThan(1);
…除了处理几年或几个月,其毫秒值不能准确计算,因为它们不是固定的持续时间。 例如,30 vs 31 vs 28 在一个月中,或一年366天 VS 365天。 在这种情况下,毫秒数将为-1。
oneAndHalfYear.Milliseconds.Should().Be(-1);
这允许您对表达式进行比较
oneAndHalfYear.Should().BeGreaterThan(twoWeeks);
(oneAndHalfYear > twoWeeks).Should().BeTrue();
(oneAndHalfYear >= twoWeeks).Should().BeTrue();
(twoDays != null).Should().BeTrue();
(twoDays >= new Time("2d")).Should().BeTrue();
twoDays.Should().BeLessThan(twoWeeks);
(twoDays < twoWeeks).Should().BeTrue();
(twoDays <= twoWeeks).Should().BeTrue();
(twoDays <= new Time("2d")).Should().BeTrue();
特殊时间值0
和-1
可以相互比较和其他时间值,尽管这是一个非常无聊的。
Time.MinusOne.Should().BeLessThan(Time.Zero);
Time.Zero.Should().BeGreaterThan(Time.MinusOne);
Time.Zero.Should().BeLessThan(twoDays);
Time.MinusOne.Should().BeLessThan(twoDays);
并断言相等
twoDays.Should().Be(new Time("2d"));
(twoDays == new Time("2d")).Should().BeTrue();
(twoDays != new Time("2.1d")).Should().BeTrue();
(new Time("2.1d") == new Time(TimeSpan.FromDays(2.1))).Should().BeTrue();
//the string "-1" is not the same as double -1 which is milliseconds
(new Time("-1") == new Time(-1)).Should().BeFalse();
(new Time("-1") == Time.MinusOne).Should().BeTrue();
时间的单位
Time
的单位指定为DateInterval
或Time
的联合,它们都将隐式转换为这两个的Union
Expect("month").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Month);
Expect("day").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Day);
Expect("hour").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Hour);
Expect("minute").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Minute);
Expect("quarter").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Quarter);
Expect("second").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Second);
Expect("week").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Week);
Expect("year").WhenSerializing<Union<DateInterval, Time>>(DateInterval.Year);
Expect("2d").WhenSerializing<Union<DateInterval, Time>>((Time)"2d");
Expect("1.16w").WhenSerializing<Union<DateInterval, Time>>((Time)TimeSpan.FromDays(8.1));
距离单位
无论何时需要指定距离,例如 对于地理距离查询,距离单位可以被指定为表示距离(以米为单位)的double数字,作为Distance
的新实例,或作为表单数量和距离单位的字符串。2.72km
NEST使用“距离”类型强烈地键入距离单位,并且有几种方式来构造一个距离单位。
构造函数
构建Distance
的最直接的方法是通过其构造函数
var unitComposed = new Distance(25);
var unitComposedWithUnits = new Distance(25, Nest.DistanceUnit.Meters);
Distance
序列化为由因子和距离单位组成的字符串。 因子是double ,所以在序列化时总是至少有一个小数位
Expect("25.0m")
.WhenSerializing(unitComposed)
.WhenSerializing(unitComposedWithUnits);
隐式转换
或者,可以将距离单位string
分配给Distance
,导致对新Distance
实例的隐式转换。 如果未指定DistanceUnit
,则默认距离单位为米
Distance distanceString = "25";
Distance distanceStringWithUnits = "25m";
Expect(new Distance(25))
.WhenSerializing(distanceString)
.WhenSerializing(distanceStringWithUnits);
支持单位
支持多个距离单位,从毫米到海里
公制
mm
(毫米)
Expect("2.0mm").WhenSerializing(new Distance(2, Nest.DistanceUnit.Millimeters));
cm
(厘米)
Expect("123.456cm").WhenSerializing(new Distance(123.456, Nest.DistanceUnit.Centimeters));
m
(米)
Expect("400.0m").WhenSerializing(new Distance(400, Nest.DistanceUnit.Meters));
km
(千米)
Expect("0.1km").WhenSerializing(new Distance(0.1, Nest.DistanceUnit.Kilometers));
英制
in
(英寸)
Expect("43.23in").WhenSerializing(new Distance(43.23, Nest.DistanceUnit.Inch));
ft
(英尺 )
Expect("3.33ft").WhenSerializing(new Distance(3.33, Nest.DistanceUnit.Feet));
yd
(码)
Expect("9.0yd").WhenSerializing(new Distance(9, Nest.DistanceUnit.Yards));
mi
(英里)
Expect("0.62mi").WhenSerializing(new Distance(0.62, Nest.DistanceUnit.Miles));
nmi
or NM
(海里)
Expect("45.5nmi").WhenSerializing(new Distance(45.5, Nest.DistanceUnit.NauticalMiles));
日期数学表达式
日期类型支持在查询/过滤器中使用时使用日期数学表达式,每当需要指定持续时间时,例如对于超时参数,可以指定持续时间
表达式以”anchor”日期开头,可以是现在,也可以以||
结尾的日期字符串(以适用的格式)。 然后可以按照数学表达式,支持+
, -
和/
(四舍五入)。 支持的单位是
y(年)
M(月)
w(周)
d(天)
h(小时)
m(分钟)
s(秒)
作为代表时间(以毫秒为单位)的整数,或作为2d
的时间值,持续2天。
请务必阅读有关Date Math的Elasticsearch文档。
简单的表达
您可以使用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";
结果日期数学将假定整个字符串是锚点
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()
)
);
复杂表达式
范围可以链接到简单的表达式
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)));
时间分数阶
DateMath
表达式不支持小数,所以与Time
不同DateMath
将选择可以表示的最大的整数单位
Expect("now+25h").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromHours(25)));
在这样的Time
,它自己的序列化这样
Expect("1.04d").WhenSerializing(new Time(TimeSpan.FromHours(25)));
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"));
Expect("now+52w").WhenSerializing(
Nest.DateMath.Now.Add(TimeSpan.FromDays(7 * 52)));