如何在Elasticsearch中对嵌套数组使用DateRange进行查询?
如何用NEST过滤嵌套数组中的日期范围?
你遇到的问题核心是没用到Elasticsearch专门处理嵌套文档的Nested查询——直接用BookingItems.First().Start会让NEST把字段解析成bookingItems.0.start,也就是只检查数组第一个元素的日期,而不是数组里任意一个符合条件的元素。
正确的实现方式
要过滤嵌套数组中存在至少一个Start日期在范围内的文档,需要用Nested查询指定嵌套路径,再在里面添加日期范围过滤:
var filter = new QueryContainerDescriptor<GrossReservationVersion2>() .Nested(nested => nested .Path(p => p.BookingItems) // 指定嵌套数组的路径 .Query(q => q .DateRange(range => range .GreaterThanOrEquals(start) .LessThanOrEquals(end) .Field(f => f.BookingItems.First().Start) // 这里的First()只是NEST用来推断字段路径的语法,实际会解析成bookingItems.start ) ) );
关键说明
为什么原来的写法不行?
f.BookingItems.First().Start是客户端Linq的写法,NEST会把它转换成bookingItems.0.start(数组索引为0的元素字段),这只会匹配第一个元素的日期符合条件的文档,而不是数组中任意一个元素符合的情况。必须确保嵌套字段的映射正确
还要注意你的BookingItems字段必须在Elasticsearch索引中被映射为nested类型(而不是默认的object类型),否则Nested查询不会生效。如果映射不对,需要先更新索引映射:{ "mappings": { "properties": { "BookingItems": { "type": "nested", "properties": { "Start": { "type": "date" } } } } } }如果需要更严格的条件
要是你想匹配所有BookingItems的Start都在日期范围内的文档,可以在Nested查询里结合Bool和MustNot来实现:var filter = new QueryContainerDescriptor<GrossReservationVersion2>() .Nested(nested => nested .Path(p => p.BookingItems) .Query(q => q .Bool(b => b .MustNot(mn => mn .DateRange(range => range .Field(f => f.BookingItems.First().Start) .LessThan(start) .Or(o => o.GreaterThan(end)) ) ) ) ) );
内容的提问来源于stack exchange,提问作者Giss
相关产品推荐
相关产品推荐

