当我们在索引日期上使用日期范围查询时,休眠搜索不会返回任何结果。
所有其他范围查询均按预期工作
除了Elasticsearch尝试在给定范围内查找日期的查询之外,我们还在elasticsearch之上使用休眠搜索。
我们还有其他有关体重,身高等范围的查询,可以按预期工作。
用卢克(Luke)检查索引,看来日期已按预期索引。
我们有以下域对象仅显示相关字段
$('commentcounter'+e.target.id).text(parseInt($('commentcounter'+e.target.id).text())+1)
我也在dateOfBirth字段上尝试了以下方法
@Indexed
public class Person{
@IndexedEmbedded
@OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
@Cascade({org.hibernate.annotations.CascadeType.PERSIST})
private Set<DateOfBirth> datesOfBirth = new HashSet<>();
}
public class DateOfBirth{
@Basic
@Field
@DateBridge(resolution = Resolution.MILLISECOND)
@Column(name = "date_of_birth")
private Date dateOfBirth;
}
我们将以下代码添加到查询中,以查找从用户界面传递的所有年龄段的人
@Basic
@Field(bridge = @FieldBridge( impl = ElasticsearchDateBridge.class))
@Column(name = "date_of_birth")
@JsonFormat(pattern = "dd/MM/yyyy")
private Date dateOfBirth;
在执行查询之前先对其进行检查
public void withAgeRange(Integer lowerAge, Integer upperAge){
if(lowerAge != null || upperAge != null){
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime lowerLocalDateTime = localDateTime.withYear(localDateTime.getYear() - upperAge);
LocalDateTime upperLocalDateTime = localDateTime.withYear(localDateTime.getYear() - lowerAge);
Date lowerDate = Date.from(lowerLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
Date upperDate = Date.from(upperLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
bool.must(getQueryBuilder().range().onField("datesOfBirth.dateOfBirth").from(lowerDate).to(upperDate).createQuery());
}
}
以卢克(Luke)为例查看示例文档,该人的出生日期的索引值为320976000000,该范围介于上下限之间。
来自Kibana的人员映射的相关部分
+dateOfBirths.dateOfBirth:[33590595604 TO 1106595795604]
如前所述,我们所有其他范围查询均按预期工作。
我们希望至少返回一个人,但是无论我们尝试在什么范围内,我们始终会返回0个结果。
任何想法都将不胜感激。
答案 0 :(得分:1)
看起来像这样可能是时区问题...
好像您正在使用java.util.Date存储数据。以我的经验,这不会将时区信息传递给Elasticsearch。 Elasticsearch stores dates internally using UTC。如果经过了时区,则ES会在实际存储时区时将其转换为UTC。如果未经过任何时区,则ES会假设您的日期为世界标准时间。
这是什么意思:假设您正在美国西部时区(GMT-8)上运行,这意味着ES会认为您的意思是您的日期要比传递的日期早8小时成为。例如,您输入的出生日期为“ 01/25/19:12:00:00”,ES会在UTC中将其视为实际日期,实际上是您的“ 01/25/19:4:00:00”时间。意思是,您尝试运行的任何查询都需要在-8个小时内进行调整,以使文档目前处于索引状态。从您的代码来看,您正在调整查询以适应您的时区,但实际上并未编入索引。
为什么您所有其他查询都能按预期运行,但我不确定这不是,但是我的直觉是上面的。
为了解决日期问题,我在UTC使用ZonedDateTime为文档建立了索引。
作为参考,这是一个问题,当我弄清楚它是在我处理类似查询问题时发布的,随后的答案是:Query to pull with timestamps that were updated more than 30m ago not working
答案 1 :(得分:0)
如果我们用
进行注释@Basic
@Field(bridge = @FieldBridge( impl = ElasticsearchDateBridge.class))
@Column(name = "date_of_birth")
@JsonFormat(pattern = "dd/MM/yyyy")
private Date dateOfBirth;
并将查询更改为
bool.must(getQueryBuilder().range().onField("datesOfBirth.dateOfBirth").ignoreFieldBridge().from(dateFormat.format(lowerDate)).to(dateFormat.format(upperDate)).createQuery());
dateFormat在哪里
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
它按预期工作。
不确定这是否是最好的方法。还是有更好的方法呢?
似乎有点混乱。