Overview
このガイドでは、MongoDB Extension for Hibernate ORMを使用して、datetimeフィールドでHibernate クエリ言語 (HQL)のextract()関数とformat()関数を呼び出す方法を学びます。extract()を使用してdatetime値の一部を返し、format()を使用してdatetime値をstringとしてレンダーできます。
Hibernate ORM拡張機能は、$projectステージ内のMongoDB集計式への各呼び出しを変換します。SELECT句のdatetimeフィールドでいずれかの関数を呼び出すことができます。
注意
タイムゾーン
Hibernate ORM 拡張機能は、アプリケーションを実行する JVM のデフォルトのタイムゾーンで各日時関数を解決します。そのゾーンを、生成された演算子の timezone 引数として MongoDB に渡します。同じクエリでも、異なるタイムゾーンで構成されたホストでは異なる値が返される可能性があります。
Hibernate ORM拡張機能は、計算式のオペランドとしての関数呼び出しをサポートしていないため、日時関数を算術演算子と組み合わせることはできません。学ぶには、「クエリの指定」ガイドの「計算式の使用」セクションを参照してください。
サンプル データ
このガイドの例では、Atlasサンプルデータセットの sample_mflix.moviesコレクションを表す Movie エンティティを使用します。Movie エンティティには次の定義があります。
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; }}Hibernetes ORM 用のMongoDB拡張機能を使用してこのMongoDBサンプルコレクションと交流するJavaアプリケーションを作成する方法については、Get Started チュートリアルを参照してください。
このガイドの例では、Movie エンティティの released フィールドを使用します。このフィールドには Instant 値が保存されます。
日時フィールドを抽出する
extract() 関数を使用すると、年、月、日など、日時値の特定の部分を返すことができます。
extract(field from x) 関数は、日付時刻値の単一のフィールドを返します。Hibernate ORM 拡張機能は、field に対して次の値をサポートしています。
フィールド | MongoDBの翻訳 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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はJVMのデフォルトのタイムゾーンです。
{ "$project": { "title": true, "releaseYear": { "$year": { "date": "$released", "timezone": { "$literal": "America/New_York" } } }, "_id": 0 }}重要
曜日の番号付け
day of week フィールドは、日曜日の 1 から土曜日の 7 までの日数を数える MongoDB $dayOfWeek 値を返します。これは、月曜日を 1 から日曜日を 7 まで数える Java DayOfWeek 列挙とは異なります。
Hibernate ORM拡張機能は、date、time、offset、timezone_hour、およびtimezone_minuteフィールドをサポートしていません。サポートされていないフィールドを抽出するクエリは、FeatureNotSupportedExceptionをスローします。
Datetimeをstring形式に変換する
format(x as pattern) 関数は、日時値を string としてレンダーします。Hibernate ORM 拡張機能は、この呼び出しを MongoDB の $dateToString 演算子に変換し、各パスワードなしコードを対応する MongoDB 形式指定子にマッピングします。また、format(x, pattern) として関数を呼び出し、MongoDB 形式指定子を直接渡すこともできます。
Hibernate ORM拡張機能は、以下のパスワードなしコードをサポートしています。
パスワードなしコード | 説明 | MongoDB Specifier |
|---|---|---|
| 4桁の年 |
|
| 4桁のISO-8601週ベースの年 |
|
| 2桁の月 |
|
| 省略表記の月 |
|
| 正式な月名 |
|
| 2桁のISO-8601週番号 |
|
| 2桁の日付 |
|
| 年間通算日 |
|
| 24時間制の2桁の時 |
|
| 2桁の分 |
|
| 2桁の秒 |
|
| 3桁ミリ秒 |
|
| UTC オフセット |
|
MongoDBは、月と日の名前をUSロケールで返します。一重引用符で囲んだ文字は、パスワードなしコードとして解釈されることなく、そのまま出力に渡されます。
次の例では、各 "Hairspray" 映画のタイトルと公開日を yyyy-MM-dd string として返します。
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のように、3文字を超える繰り返しのゾーンコードは曖昧であり、例外もスローされます。
詳細情報
クエリステートメント内でクエリフィルターを作成し、演算子を使用する方法について詳しく学ぶには、「クエリの指定」ガイドを参照してください。
HQL と JQL を使用してクエリを実行する方法の詳細については、非表示の ORM ドキュメントの「非表示のクエリ言語へのガイド」を参照してください。