java—使用jdbc和mongodb查询以字符串形式存储的日期

hrysbysz  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(644)

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

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

如您所见,日期存储为字符串,而不是isodate对象。据我所知,mongodb应该仍然能够将其作为日期进行处理和查询((来源)
因此,我尝试用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()方法将知道我要查询一个日期,并且它将按照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的原始版本确实应该知道,我查询的是一个日期而不是一个字符串,它只是在某种程度上无法将数据库中的日期转换为日期类型?我不知道该怎么做。
我知道这是一种特殊的用法,我真的应该在mongodb中插入isodate,但是在我现在的特殊情况下,这不是一个选项。
如果我使用的是jdbc,有没有办法查询mongodb中作为字符串存储的日期?

o4tp2gmn

o4tp2gmn1#

次要的一点:您正在使用mongodb的java连接器。jdbc驱动程序用于使用sql查询语言的关系数据库。因此我改变了主意 JDBC 标记到 Java 在你的问题上。
使用日期作为字符串
关于文档中的日期时间格式:由于您使用的格式以及它存储为字符串,因此在运行查询时可以使用字符串比较。词法排序将确保字符串比较等同于日期时间比较。这是您链接到的问题中的代码正在使用的内容。
显然,如果您有任何以其他字符串格式存储的数据,例如“dd-mm-yyyy”,其中的字符串顺序与日期时间顺序不匹配,则此假设将被打破。
不管怎样,您都应该避免使用旧的和有问题的java Date 以及 Calendar 班级。相反,使用现代的 java.time 班级。更多背景信息。
在您的例子中,您的文档存储的日期时间数据没有任何时区或偏移信息。你可以用 java.time.LocalDateTime 为了这个。这个名字中的“local”一词实际上意味着“没有特定的地点或时区”——这与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"

将日期用作对象
如果你想使用java LocalDate 对象,而不是使用字符串比较,您可以使用投影在查询结果中创建日期对象,然后使用java LocalDate 对象直接在筛选器中:

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 运算符没有指定时区-因此它默认为zulu时间(ut时区),如下面的示例输出所示:

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

相关问题