当前位置: 首页 > 知识库问答 >
问题:

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

蒯硕
2023-03-14

因此,正如标题所示,我的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。日期,然后是过滤器。gte()方法将知道我的意思是查询一个日期,它将按照MongoDB中的预期工作。然而,我得到了0个匹配项。

我还尝试在我的queryDate上安装格式化程序(之前出于不同的目的):

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

然而,这导致了过滤器的损坏。gte()将其作为字符串查询,根据字符串比较,大致按字母顺序排列。这让我一开始认为,最初的java。util。Date version确实应该知道,我查询的是一个日期,而不是一个字符串,它只是无法将数据库中的日期转换为日期类型?我不确定该怎么做。

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

如果我使用JDBC,有没有办法查询MongoDB中以字符串形式存储的日期?

共有1个答案

濮阳赞
2023-03-14

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

使用日期作为字符串

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

显然,如果您以其他字符串格式存储任何数据,例如"dd-MM-yyyy",其中字符串顺序与日期时间顺序不匹配,则此假设将被打破。

无论您如何继续,都应该避免使用旧的、有问题的JavaDateCalendar类。相反,使用现代的java。时间课程。这里有更多的背景。

在您的情况下,您的文档存储的是日期时间数据,没有任何时区或偏移量信息。你可以使用java。时间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"

使用日期作为对象

如果要在查询中直接使用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操作符时没有指定时区,因此它默认为Zulu时间(UT时区),如下面的示例输出所示:

{
    "_id": {
        "$oid": "5fcf541b466a3d10f55f8241"
    },
    "dateOfBirth": "1992-11-02T12:05:17",
    "birthDate": {
        "$date": "1992-11-02T12:05:17Z"
    }
}
 类似资料:
  • 问题内容: 所以这是我的问题。我有一个存储mongodbs对象的数组。使用mgo和bson包在一个查询中全部检索它们的正确方法是什么? 因此,如果数组是这样的: 我们如何进行查询?我尝试过,但是我知道它是错误的。 提前致谢 问题答案: 如果文档使用字符串ID存储,则代码看起来正确。 这些ID看起来像十六进制编码的对象ID。如果对象标识符是对象ID,则需要将十六进制字符串转换为对象ID:

  • 问题内容: 我需要一些帮助,以便在mongodb和nodejs中按日期查找记录。 我将日期添加到抓取脚本中的json对象中,如下所示: 该对象被插入到mongodb中。我可以看到如下: 然后在我的nodejs脚本中执行findOne(): 找不到对象。如果我从对象中删除last_updated字段,则会找到它,因此绝对是问题所在。 如果我按以下方式隔离字段: 什么也没有回来。请问我做错了什么? 问

  • 问题内容: 我正在尝试在mongodb中执行查询日期,但结果始终为空。我的查询如下: //变量resultaMongo返回空。 Obs:我也尝试不使用.isoformat(),当我直接放入mongodb时,只有添加ISODate才返回结果。因此不会返回结果: 更重要的是,如果您编辑返回: 这是数据库中的记录序列: 如果我打印python的json变量,则会看到类似以下内容的内容: 我的Mongnd

  • 我有一个解析模板,它将从appsync查询中获取开始日期作为日期。但我在迪纳摩的约会是有日期时间戳的。我们如何在没有时间的情况下比较这两个日期。以下是我的解析器模板查询:

  • 我需要检查执行查询时使用的内存。我已经在MYSQL中将JDBC连接到我的数据库。我也知道如何执行查询。但是我不知道如何检查执行查询时使用的内存。这是为了比较内存和时间。我使用NetBeans。 非常感谢。

  • 如何将查询结果保存在字符串数组中 查询很简单,只有一列,即: 我想要的是将id存储在String数组中,这样我就可以将它们显示为列表视图中的可点击项。