使用JDBC和MongoDB来查询存储在String中的日期



因此,如标题所示,我的MongoDB数据库中有以下示例文档:

{"_id":{"$oid":"5fcf541b466a3d10f55f8241"}, "dateOfBirth":"1992-11-02T12:05:17"}

正如您所看到的,日期存储为String,而不是ISODate对象。据我所知,MongoDB应该仍然能够将其作为Date进行处理和查询。(来源(

因此,我试图用JDBC在我的java应用程序中以以下方式查询它:

java.util.Date queryDate = new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime();
Bson query = Filters.gte("dateOfBirth", queryDate);
FindIterable<Document> result = collection.find(query);

然而,这是行不通的。我的想法是,如果我传入java.util.Date,那么Filters.gte((方法就会知道我的意思是查询Date,它将在MongoDB中按预期工作。但是,我得到0个匹配项。

我还试着在queryDate上放一个格式化程序(之前有不同的用途(:

DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Bson query = Filters.gte("dateOfBirth", dformat.format(queryDate));

然而,这导致Filters.gte((根据字符串比较将其查询为字符串,因此大致按字母顺序排列。这让我最初认为,最初的java.util.Date版本确实/应该知道,当时我查询的是Date,而不是String,它只是不知何故未能将数据库中的日期类型转换为日期类型?我不确定它应该如何工作。

我知道这是一种特殊情况下的用法,我真的应该在mongoDB中插入日期作为ISODate,但在我现在的特殊情况下,这不是一种选择。

如果我使用JDBC,有没有一种方法可以查询存储在MongoDB中的字符串日期?

次要的一点:您正在使用MongoDB的Java连接器。JDBC驱动程序适用于使用SQL查询语言的关系数据库。因此,我在您的问题中将JDBC标记更改为Java

将日期作为字符串使用

关于文档中的日期时间格式:由于您使用的格式以及它存储为字符串,因此在运行查询时可以使用字符串比较。词汇排序将确保字符串比较等效于日期时间比较。这是你链接到的问题中的代码正在使用的内容。

显然,如果您有任何以其他字符串格式存储的数据,例如";dd-MM-yyyy";,其中字符串排序与日期时间排序不匹配。

但是,您应该避免使用旧的和有问题的JavaDateCalendar类。相反,请使用现代的java.time类。更多背景信息请点击此处。

在您的情况下,您的文档存储的日期时间数据没有任何时区或偏移信息。您可以使用java.time.LocalDateTime。单词";本地";在这个名称中实际上意味着";没有特定的地点或时区"-这与Mongo文档中的内容相匹配。

Java导入:

import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;

本地日期时间示例:

LocalDateTime ldt = LocalDateTime.of(1980, Month.JANUARY, 1, 0, 0);
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
String s = ldt.format(dtf); // "1980-01-01T00:00:00"

使用日期作为对象

如果您想在查询中直接使用JavaLocalDate对象,而不是使用字符串比较,您可以使用投影在查询结果中创建日期对象,然后在过滤器中直接使用JavaLocalDate对象:

Bson resultsWithDate = Aggregates.project(Projections.fields(
Projections.include("dateOfBirth"),
Projections.computed("birthDate", Projections.computed("$toDate", "$dateOfBirth"))
));

上面的投影为每个检索到的文档添加了一个新的dateOfBirth字段,并通过$toDate运算符填充它。

然后我们可以应用我们的过滤器:

collection.aggregate(
Arrays.asList(
resultsWithDate,
Aggregates.match(Filters.gte("birthDate", ldt)))
).forEach(printConsumer);

过滤器现在使用上面的ldt对象。

我使用以下助手方法在控制台中将每个结果文档打印为JSON字符串:

Consumer<Document> printConsumer = (final Document document) -> {
System.out.println(document.toJson());
};

可能有一种更紧凑或更高效的方法来构建这个MongoDB聚合——我不是Mongo的普通用户。

此外,最后要注意的是:我使用的Mongo$toDate运算符没有指定时区,因此它默认为祖鲁时间(UT时区(,如下面的示例输出所示:

{
"_id": {
"$oid": "5fcf541b466a3d10f55f8241"
},
"dateOfBirth": "1992-11-02T12:05:17",
"birthDate": {
"$date": "1992-11-02T12:05:17Z"
}
}

最新更新