对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
See how MongoDB 9.0 delivers up to 2x higher throughput.
MongoDB Branding Shape
Register now >
Docs 菜单

在查询中使用日期时间函数

在本指南中,您可以学习;了解如何使用MongoDB Extension for Hibernate ORM 在日期时间字段上调用 Hibernate Query Language (HQL) extract() 和 format() 函数。您可以使用 extract() 返回日期时间值的一部分,并使用 format() 将日期时间值呈现为字符串。

Hibernate ORM 扩展将每个调用转换为 $project 阶段中的MongoDB聚合表达式。您可以在 SELECT 子句中对日期时间字段调用任一函数。

注意

时区

Hibernate ORM 扩展在运行应用程序的Java虚拟机(JVM)的默认时区域中解析每个日期时间函数。它将该区域作为生成的操作符符的 timezone 参数传递给MongoDB 。在配置了不同时区的主机上,同一查询可能会返回不同的值。

由于 Hibernate ORM 扩展不支持将函数调用作为计算表达式的操作数,因此您无法将日期时间函数与算术操作符组合使用。要学习;了解更多信息,请参阅指定查询指南中的使用计算表达式部分。

The examples in this guide use the Movie entity, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie entity has the following definition:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.time.Instant;
import java.util.List;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
private List<String> directors;
private Instant released;
@Embedded
private Awards awards;
@OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
private List<Comment> comments;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
this.released = released;
this.awards = awards;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
public List<String> getDirectors() {
return directors;
}
public void setDirectors(List<String> directors) {
this.directors = directors;
}
public Awards getAwards() {
return awards;
}
public void setAwards(Awards awards) {
this.awards = awards;
}
public Instant getReleased() {
return released;
}
public void setReleased(Instant released) {
this.released = released;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}

学习如何创建使用 MongoDB Extension for Hibernate ORM 与此 MongoDB 示例集合交互的 Java 应用程序,请参阅 入门 教程。

本指南中的示例使用 Movie 实体的 released字段,其中存储了 Instant 值。

您可以使用 extract() 函数返回日期时间值的特定部分,例如年、月或日。

extract(field from x) 函数返回日期时间值的单个字段。 Hibernate ORM 扩展支持以下 field 值:

字段
MongoDB翻译

year

$year

quarter

通过将 $month 除以 3 并向上舍入来计算

month

$month

week

$isoWeek,返回 ISO-8601 周编号

week of year

根据 $dayOfYear 和 $dayOfWeek 计算为基于星期日的周数

week of month

根据 $dayOfMonth 和 $dayOfWeek 计算为基于星期日的周数

day, day of month

$dayOfMonth

day of week

$dayOfWeek

day of year

$dayOfYear

hour

$hour

minute

$minute

second

根据 $second 和 $millisecond 计算为秒的小数部分

nanosecond

根据 $second 和 $millisecond 计算

epoch

计算方式为自 Unix 纪元以来的整数秒数

以下示例返回 sample_mflix.movies集合中每部 "Hairspray" 电影的标题以及电影的发行年份:

var extractResult = session.createQuery(
"select title, extract(year from released) as releaseYear from Movie where title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : extractResult) {
System.out.println("Title: " + row[0] + ", Release Year: " + row[1]);
}
var extractResult = entityManager.createQuery(
"select m.title, extract(year from m.released) as releaseYear from Movie m where m.title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : extractResult) {
System.out.println("Title: " + row[0] + ", Release Year: " + row[1]);
}

Hibernate ORM 扩展将前面的查询转换为以下 $project 阶段,其中 America/New_York 是Java虚拟机(JVM)的默认时区域:

{
"$project": {
"title": true,
"releaseYear": {
"$year": {
"date": "$released",
"timezone": { "$literal": "America/New_York" }
}
},
"_id": 0
}
}

重要

星期编号

day of week字段返回MongoDB $dayOfWeek 值,该值从 1(星期日)到 7(星期六)对天数进行编号。这与Java DayOfWeek枚举不同,后者对从星期一的 1 到星期日的 7 之间的天数进行编号。

Hibernate ORM 扩展不支持date、time、offset、timezone_hour 和 timezone_minute 字段。提取不支持字段的查询会引发 FeatureNotSupportedException。

format(x as pattern) 函数将日期时间值呈现为字符串。 Hibernate ORM 扩展会将调用转换为MongoDB $dateToString操作符,并将每个模式代码映射到等效的MongoDB格式说明符。您还可以以 format(x, pattern) 形式调用该函数,并直接传递MongoDB格式说明符。

Hibernate ORM 扩展支持以下模式代码:

模式代码
说明
MongoDB说明符

yyyy

四位数的年份

%Y

YYYY

基于周的四位 ISO-8601 年份

%G

MM

两位数的月份

%m

MMM

月份名称缩写

%b

MMMM

完整月份名称

%B

ww

两位数 ISO-8601 周编号

%V

dd

两位数的月份日期

%d

DDD

年中的某一天

%j

HH

两位数的小时数,采用 24 小时制

%H

mm

两位数的分钟数

%M

ss

两位数秒数

%S

SSS

三位数毫秒

%L

Z, ZZ , ZZZ , xx

UTC 偏移量

%z

MongoDB返回美国区域设置中的月份和日期名称。用单引号括起来的字符会传递到输出,而不会被解释为模式代码。

以下示例以 yyyy-MM-dd 字符串的形式返回每部 "Hairspray" 电影的标题及其发布日期:

var formatResult = session.createQuery(
"select title, format(released as 'yyyy-MM-dd') as releaseDate from Movie where title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : formatResult) {
System.out.println("Title: " + row[0] + ", Release Date: " + row[1]);
}

如果要改用MongoDB格式说明符,则可以以 format(released, '%Y-%m-%d') 的形式调用该函数。

var formatResult = entityManager.createQuery(
"select m.title, format(m.released as 'yyyy-MM-dd') as releaseDate from Movie m where m.title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : formatResult) {
System.out.println("Title: " + row[0] + ", Release Date: " + row[1]);
}

如果要改用MongoDB格式说明符,则可以以 format(m.released, '%Y-%m-%d') 的形式调用该函数。

Hibernate ORM 扩展将前面的查询转换为以下 $project 阶段:

{
"$project": {
"title": true,
"releaseDate": {
"$dateToString": {
"date": "$released",
"format": { "$literal": "%Y-%m-%d" },
"timezone": { "$literal": "America/New_York" }
}
},
"_id": 0
}
}

使用上表之外的模式代码的查询会抛出 FeatureNotSupportedException。这包括单字符和可变宽度代码,如 y、M、d、H、h、m、s 和 a,因为MongoDB没有等效的说明符。超过三个字符的重复时区域代码(例如 ZZZZZZZ)是不明确的,也会引发异常。

要学习;了解有关创建查询筛选器和在查询语句中使用操作符的更多信息,请参阅“指定查询”指南。

要了解有关使用 HQL 和 JPQL 运行查询的更多信息,请参阅 Hibernate ORM 文档中的 Hibernate 查询语言指南。