AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

クエリを指定する

このガイドでは、Hibernate ORM 用の MongoDB 拡張機能を使用してデータベースクエリを指定する方法を学習します。

クエリフィルターを作成することで、クエリが返すドキュメントのセットを絞り込むことができます。クエリフィルターは、MongoDB が読み取りまたは書き込み (write) 操作においてドキュメントを照合するために使用する検索する条件を指定する式です。MongoDBクエリフィルターを作成するには、 非表示クエリ言語(HQL) または Java 永続クエリ言語(JQL) ステートメントを使用します。

Tip

HQL および JQL の構文の詳細については、非表示の ORM ドキュメントの「非表示のクエリ言語へのガイド」を参照してください。

注意

クエリ サポート

Hibernate ORM 用のMongoDB拡張機能は、すべてのMongoDBおよびHibernateのクエリ機能をサポートしていません。詳細については、 機能の互換性 ページの「クエリ サポート」を参照してください。

このガイドの例では、AtlasサンプルデータセットのMovie sample_mflix.moviesコレクションを表す エンティティを使用します。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 チュートリアルを参照してください。

このページのコード例では、次の Awards @Struct 集計埋め込みも使用しています。

@Embeddable
@Struct(name = "Awards")
public class Awards {
private int wins;
private int nominations;
private String text;
public Awards(int wins, int nominations, String text) {
this.wins = wins;
this.nominations = nominations;
this.text = text;
}
public Awards() {
}
public int getWins() {
return wins;
}
public void setWins(int wins) {
this.wins = wins;
}
public int getNominations() {
return nominations;
}
public void setNominations(int nominations) {
this.nominations = nominations;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}

重要

永続性コンテキスト

Hibernetes ORM を有効にしてデータベースを操作するには、 Hibernetes Session または Java 永続性 EntityManager を使用して永続性コンテキスト内で操作を実行する必要があります。セッション クエリを定義するには HQL を使用し、エンティティ マネージャー クエリを定義するには JQL を使用します。

このガイドの例を実行する前に、次のコードのような永続性コンテキストとトランザクションマネジメントコードをアプリケーションに追加していることを確認してください。

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
// ... Perform CRUD operations here
tx.commit();
session.close();
sf.close();

セッションを使用するには、SessionFactory を構成する HibernateUtil.javaファイルを作成する必要があります。詳しく学ぶには、「使い始める」チュートリアルの「アプリケーションを構成する」手順を参照してください。

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// ... Perform CRUD operations here
entityManager.getTransaction().commit();
entityManager.close();
emf.close;

EntityManager を使用するには、永続性ユニットを宣言する persistence.xmlファイルを作成する必要があります。詳細を学ぶには、Hibernate ORM ドキュメントのJPA 標準 API を使用するチュートリアルを参照してください。

SessionFactoryインスタンスを作成する前に、com.mongodb.hibernate.semantics.nulls 構成プロパティをMQL に設定する必要があります。このプロパティは必須で、デフォルト値はなく、現在他の値を受け入れていません。プロパティを省略するか、別の値に設定すると、非表示 ORM 拡張機能は HibernateException をスローします。

com.mongodb.hibernate.semantics.nulls を MQL に設定すると、プロパティは、 SQL null セマンティクスで定義された 3 値のロジックではなく、 Hibernetes ORM 拡張機能が変換中に生成するMongoDBクエリ言語(MQL )に null 関連の動作が宣言されます。

Hibernetes ORM 拡張機能は特定の翻訳を保証していないため、null 関連の動作の結果はリリース間で変更される可能性があります。

次の例では、hibernate.propertiesファイルに com.mongodb.hibernate.semantics.nullsプロパティを設定します。

com.mongodb.hibernate.semantics.nulls=MQL

クエリ ステートメントで次の演算子を使用して、フィールド値を指定されたクエリ値と比較できます。

  • =: 等価一致

  • <>: 等価一致

  • >: 比較より大きい

  • >=: 以上の比較

  • <: 比較より小さい

  • <=: 以下の比較

次の例では、sample_mflix.moviesコレクションから、year の値が 2015 以上であるドキュメントを検索します。

var comparisonResult = session.createQuery("from Movie where year >= :y", Movie.class)
.setParameter("y", 2015)
.getResultList();
for (var m : comparisonResult) {
System.out.println("Title: " + m.getTitle());
}
var comparisonResult = entityManager.createQuery("select m from Movie m where m.year >= :y", Movie.class)
.setParameter("y", 2015)
.getResultList();
for (var m : comparisonResult) {
System.out.println("Title: " + m.getTitle());
}

行値述語は、フィールドの挿入リストと値の挿入リストを単一の式で比較します。 Hibernetes ORM 拡張機能は、次の演算子を使用する行値述語をサポートします。

  • =: 等価一致

  • <>: 等価一致

  • IN および NOT IN: 値行のリストと照合

値は バインドされたパラメーターまたはリテラルとして指定できます。また、各リストには同じ数のコンポーネントが含まれている必要があります。

次の例では、 sample_mflix.moviesコレクションから、title 値が "Jurassic World" で、かつ year 値が 2015 であるドキュメントを検索します。

var rowValueResult = session.createQuery("from Movie where (title, year) = (:t, :y)", Movie.class)
.setParameter("t", "Jurassic World")
.setParameter("y", 2015)
.getResultList();
for (var m : rowValueResult) {
System.out.println("Title: " + m.getTitle());
}
var rowValueResult = entityManager.createQuery("select m from Movie m where (m.title, m.year) = (:t, :y)", Movie.class)
.setParameter("t", "Jurassic World")
.setParameter("y", 2015)
.getResultList();
for (var m : rowValueResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、各コンポーネントのペアを個別に比較します。上記の行値述語は、次の $match ステージに変換されます。

{
"$match": {
"$and": [
{ "title": { "$eq": "Jurassic World" } },
{ "year": { "$eq": 2015 } }
]
}
}

<> 演算子を使用する行値述語は、 $nor式でラップされた同じ $and式に変換されます。

where (title1, year1) = (title2, year2) のように、フィールドを別のフィールドのリストと比較する場合、 Hibernetes ORM 拡張機能 は代わりに述語を $expr式に変換します。

SELECT 句では行値述語を使用できます。述語がプロジェクションでブール値値として評価されます。

注意

null セマンティクス

行値述語は、 Hibernetes ORM 三項ロジックではなく、 MongoDBクエリ言語の null セマンティクスに従うため、<> 述語は、コンポーネントが null または欠落しているドキュメントと一致します。詳細については、このガイドの「 Null とのフィールド値の比較 」セクションを参照してください。

フィールド行を複数行の値と照合するには、IN 演算子を使用します。次の例では、title と year の 2 つのペアのいずれかに一致するドキュメントを検索します。

var rowValueInResult = session.createQuery(
"from Movie where (title, year) in (('Jurassic World', 2015), ('Ex Machina', 2015))", Movie.class)
.getResultList();
for (var m : rowValueInResult) {
System.out.println("Title: " + m.getTitle());
}
var rowValueInResult = entityManager.createQuery(
"select m from Movie m where (m.title, m.year) in (('Jurassic World', 2015), ('Ex Machina', 2015))", Movie.class)
.getResultList();
for (var m : rowValueInResult) {
System.out.println("Title: " + m.getTitle());
}

上記の行値述語は、次の $match ステージに変換されます。

{
"$match": {
"$or": [
{ "$and": [
{ "title": { "$eq": "Jurassic World" } },
{ "year": { "$eq": 2015 } }
] },
{ "$and": [
{ "title": { "$eq": "Ex Machina" } },
{ "year": { "$eq": 2015 } }
] }
]
}
}

リストに 1 行の値しか含まれていない場合、述語は $and式のみに変換されます。 NOT IN 述語は、 $nor式でラップされた $or式に変換されます。

重要

順序付けの比較

Hibernetes ORM 拡張機能は、>、>=、<、または <= 演算子を使用する行値述語をサポートしていません。これらの述語により Hibernetes ORM 拡張機能は FeatureNotSupportedException をスローします。

比較演算子を使用してフィールドをnull と比較する場合、 Hibernetes ORM 拡張機能は Hibernetes ORM が定義する三項ロジックではなく、 MongoDBクエリ言語の null セマンティクスを適用します。

注意

null の三項ロジックを一時停止

ORM v6.3 nullnullを停止し、その後 との比較をfalse として評価します。これを述語が として扱います。 Hibernetes ORM 拡張機能では、この動作は実装されていません。 Hibernetes ORM 拡張機能がサポートする機能の詳細については、 機能の互換性 ページの 「データ型のサポート」 を参照してください。

MongoDB比較演算子は、欠落しているフィールドと、null に明示的な null 値を保存しているフィールドの両方を評価します。その結果、= null を比較すると、フィールドに null が保存されているドキュメントと、フィールドが存在しないドキュメントが一致します。 <> null または != null の比較は、フィールドに他の値が保存されているドキュメントと一致します。

次の例では、= 演算子を使用して、sample_mflix.moviesコレクションから null または欠落している cast 値を持つドキュメントを検索します。

var nullComparisonResult = session.createQuery("from Movie where cast = null", Movie.class)
.getResultList();
for (var m : nullComparisonResult) {
System.out.println("Title: " + m.getTitle());
}
var nullComparisonResult = entityManager.createQuery("select m from Movie m where m.cast = null", Movie.class)
.getResultList();
for (var m : nullComparisonResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、このクエリを次の $match ステージに変換します。

{
"$match": {
"cast": { "$eq": null }
}
}

、 、 >>=<、<= 演算子を使用する比較は、存在しないフィールドのMongoDB BSON比較順序に従います。null は独自のBSONタイプであるため、 または を比較すると、フィールドに>= null が保存されているか、<= null nullが欠落しているドキュメントが一致します。> null または< null の比較では一致するドキュメントはありません。

null比較演算子の代わりに述語を使用して、 と欠損値を照合するには、このガイドの IS NULL および IS NULL ではない セクションを参照してください。

フィールド値、リテラル、クエリ パラメーターから値を計算できます。次に、SELECT 句でその値を返したり、WHERE 句で比較したりできます。 Hibernetes ORM 拡張機能は、計算式をMongoDB集計式に変換します。

Hibernetes ORM 拡張機能は、計算された式で次の算術演算子をサポートします。

  • +: 加算。これは に変換されます $add

  • -: 減算。これは以下に変換されます。 $subtract

  • *: 乗算。これは以下に変換されます。 $multiply

  • /: 除算。変換: $divide

  • 非プライマリ - と +

注意

除算は常に整数を返します

Hibernetes ORM は、 MongoDB集計パイプラインの除算をMongoDB $divide 演算子に変換します。これは常に double を返します。 Hibernetes ORM 拡張機能は、$toInt で $divide をラップすることで結果を切り捨て、結果のタイプが BIGINT の場合は $toLong をラップします。この動作は、 Hibernetes ORM PORTABLE_INTEGER_DIVISION 設定を有効にしているかどうかにかかわらず、/ 演算子と Criteria API quot() メソッドに適用されます。

div 演算子はサポートされていません。

また、計算された式内で「 比較演算子の使用 」セクションで説明されている比較演算子を使用することもできます。

重要

オペランドの制限

計算式のオペランドは、フィールド参照、リテラル、またはクエリ パラメーターである必要があります。 Hibernetes ORM 拡張機能は、オペランドとしての関数呼び出しをサポートしていません。

Hibernetate ORM は HQL % 演算子を mod() 関数呼び出しに書き換えるため、% もサポートされていません。剰余操作を実行するには、 MongoDB $mod 演算子に変換される Criteria API CriteriaBuilder.mod() メソッドを使用します。

Criteria API CriteriaBuilder.quot() メソッドは / 演算子と同じように動作します。

計算式を選択すると、 Hibernetes ORM 拡張機能 は計算された値を $project ステージに追加します。 AS キーワードを使用して式に式を割り当てると、 Hibernetes ORM 拡張機能はプロジェクションキーとしてエイリアスを使用します。それ以外の場合は、#c_<n> の形式でキーを生成します。

次の例では、クエリ パラメータから yearフィールド値を減算して、sample_mflix.moviesコレクション内の各 "Hairspray" 映画の経過時間を計算します。

var arithmeticResult = session.createQuery(
"select title, :currentYear - year as age from Movie where title = :title",
Object[].class)
.setParameter("currentYear", 2026)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : arithmeticResult) {
System.out.println("Title: " + row[0] + ", Age: " + row[1]);
}
var arithmeticResult = entityManager.createQuery(
"select m.title, :currentYear - m.year as age from Movie m where m.title = :title",
Object[].class)
.setParameter("currentYear", 2026)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : arithmeticResult) {
System.out.println("Title: " + row[0] + ", Age: " + row[1]);
}

Hibernetes ORM 拡張機能は、前述の計算式を次の $project ステージに変換します。

{
"$project": {
"title": true,
"age": { "$subtract": [ 2026, "$year" ] },
"_id": 0
}
}

WHERE句では、計算式を値と比較したり、2 つのフィールド値を相互に比較したりできます。比較のどちらの側も直接フィールド参照または値でない場合、 Hibernetes ORM 拡張機能はMongoDB $expr 演算子で比較をラップします。フィールドと値の比較では、引き続き圧縮された{ field: { operator: value } } 形式を使用します。

次の例では、2026 より前に公開された 20 年未満にリリースされた "Hairspray" 映画を検索します。

var computedFilterResult = session.createQuery(
"from Movie where title = :title and :currentYear - year < 20", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("currentYear", 2026)
.getResultList();
for (var m : computedFilterResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var computedFilterResult = entityManager.createQuery(
"select m from Movie m where m.title = :title and :currentYear - m.year < 20",
Movie.class)
.setParameter("title", "Hairspray")
.setParameter("currentYear", 2026)
.getResultList();
for (var m : computedFilterResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

Hibernetes ORM 拡張機能は前述のクエリを次の $match ステージに変換します。ここでは、title 比較では圧縮形式が使用され、計算比較では $expr が使用されます。

{
"$match": {
"$and": [
{ "title": { "$eq": "Hairspray" } },
{ "$expr": { "$lt": [ { "$subtract": [ 2026, "$year" ] }, 20 ] } }
]
}
}

ブール値をフィルタとして使用する代わりに、SELECT ステートメントで比較を使用してブール値結果を返すことができます。

次の例では、各 "Hairspray" 映画のタイトルと、その映画が 2000 後にリリースされたかどうかを返します。

var comparisonResult = session.createQuery(
"select title, year > 2000 as isRecent from Movie where title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : comparisonResult) {
System.out.println("Title: " + row[0] + ", Recent: " + row[1]);
}
var comparisonResult = entityManager.createQuery(
"select m.title, m.year > 2000 as isRecent from Movie m where m.title = :title",
Object[].class)
.setParameter("title", "Hairspray")
.getResultList();
for (var row : comparisonResult) {
System.out.println("Title: " + row[0] + ", Recent: " + row[1]);
}

Hibernetes ORM 拡張機能は、前述の比較を次の $project ステージに変換します。

{
"$project": {
"title": true,
"isRecent": { "$gt": [ "$year", 2000 ] },
"_id": 0
}
}

Hibernetes ORM 拡張機能は、クエリ ステートメントで次の述語比較演算子をサポートします。

注意

Hibernetes ORM 拡張機能はすべての比較演算子をサポートしていません。サポート制限の詳細については、 機能の互換性 ページの 「クエリ サポート」 を参照してください。

EXISTS 述語は、特定のフィールドを持つドキュメントに一致し、一致する配列要素の数に関係なく、一致する親ドキュメントごとに 1 つの結果のみを返します。

注意

EXITS サブクエリの制限

Hibernetes ORM 拡張機能は、親エンティティの配列フィールドに対する のみ、および WHERE 句内でのみ EXISTS サブクエリをサポートします。 Hibernetes ORM 拡張機能は、次の条件を満たす EXISTS サブクエリをサポートしていません。

  • 最初にフィールドを指定せずにエンティティに対するクエリ

  • 同じ親ドキュメント内のフィールドを比較

  • SELECT 句に表示される

完全な例については、このガイドの「 埋め込み配列の要素に対するクエリ 」セクションを参照してください。

BETWEEN 述語は、指定された範囲内のフィールド値を持つドキュメントと一致します。

次の例では、BETWEEN 述語を使用して、sample_mflix.moviesコレクションから、2012 から 2013 までの year 値を持つドキュメントを検索します。

var betweenResult = session.createQuery("from Movie where year between :start and :end", Movie.class)
.setParameter("start", 2012)
.setParameter("end", 2013)
.getResultList();
for (var m : betweenResult) {
System.out.println("Title: " + m.getTitle());
}
var betweenResult = entityManager.createQuery("select m from Movie m where m.year between :start and :end", Movie.class)
.setParameter("start", 2012)
.setParameter("end", 2013)
.getResultList();
for (var m : betweenResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、先行する BETWEEN 述語を次の $match ステージに変換します。

{
"$match": {
"year": { "$gte": 2012, "$lte": 2013 }
}
}

IN 述語は、フィールド値が指定されたリスト内の任意の値と等しいドキュメントに一致します。リスト値は、リテラル、名前付きパラメータ、または位置指定パラメータとして指定できます。

次の例では、IN 述語を使用して、sample_mflix.moviesコレクションから year 値が 1994 または 1996 であるドキュメントを検索します。

var inResult = session.createQuery("from Movie where year in (:first, :second)", Movie.class)
.setParameter("first", 1994)
.setParameter("second", 1996)
.getResultList();
for (var m : inResult) {
System.out.println("Title: " + m.getTitle());
}
var inResult = entityManager.createQuery("select m from Movie m where m.year in (:first, :second)", Movie.class)
.setParameter("first", 1994)
.setParameter("second", 1996)
.getResultList();
for (var m : inResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、先行する IN 述語を次の $match ステージに変換します。

{
"$match": {
"year": { "$in": [ 1994, 1996 ] }
}
}

空のリストは有効ですが、どのドキュメントにも一致することはありません。例、year in () はどのドキュメントにも一致しません。

注意

IN 述語の制限

Hibernetes ORM 拡張機能は、IN の左側の値がフィールドパスの場合にのみ IN 述語をサポートします。 Hibernetes ORM 拡張機能は、以下の IN 述語をサポートしていません。

  • 値のリストとしてサブクエリを取得します。

  • 配列値のある式に対して値をテストします(:value in m.cast など)。配列フィールドと値を照合するには、代わりに array_contains() 関数を使用します。

配列のクエリの詳細については、このガイドの「 配列フィールドのクエリ 」セクションを参照してください。

NOT IN 述語は、フィールド値が指定されたリスト内のどの値とも等しくないドキュメントに一致します。 NOT IN は同じリスト形式を受け入れ、制限は IN 述語と同じです。

次の例では、NOT IN 述語を使用して、sample_mflix.moviesコレクションから "Romeo and Juliet" または "Best in Show" 以外の title 値を持つドキュメントを検索します。 NOT IN ではリストされている値のみが除外されるため、この例ではsetMaxResults() メソッドを呼び出して結果セットを 10 個のドキュメントに制限します。

var notInResult = session.createQuery("from Movie where title not in (:first, :second)", Movie.class)
.setParameter("first", "Romeo and Juliet")
.setParameter("second", "Best in Show")
.setMaxResults(10)
.getResultList();
for (var m : notInResult) {
System.out.println("Title: " + m.getTitle());
}
var notInResult = entityManager.createQuery("select m from Movie m where m.title not in (:first, :second)", Movie.class)
.setParameter("first", "Romeo and Juliet")
.setParameter("second", "Best in Show")
.setMaxResults(10)
.getResultList();
for (var m : notInResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、先行する NOT IN 述語を次の $match ステージに変換します。

{
"$match": {
"title": { "$nin": [ "Romeo and Juliet", "Best in Show" ] }
}
}

$nin はすべてのドキュメントを値の空のリストと照合するため、title not in () はすべてのドキュメントと一致します。

注意

NULLではない制限

Hibernetes ORM 拡張機能は、NOT IN の左側の値がフィールドパスの場合にのみ NOT IN 述語をサポートします。 Hibernetes ORM 拡張機能は、以下の NOT IN 述語をサポートしていません。

  • 値のリストとしてサブクエリを取得します。

  • 配列値のある式に対して値をテストします(:value not in m.cast など)。

注意

null セマンティクス

行値述語は、 Hibernetes ORM 三項ロジックではなく、 MongoDBクエリ言語の null セマンティクスに従うため、NOT IN 述語は、コンポーネントが null または欠落しているドキュメントと一致します。詳細については、このガイドの「 Null とのフィールド値の比較 」セクションを参照してください。

IS NULL 述語は、null または欠損値を持つ特定のフィールドを持つドキュメントに一致します。

述語の代わりに比較演算子を使用してフィールドを と比較するには、このガイドの「 フィールド値を null と比較する 」セクションを参照してください。null

次の例では、IS NULL 述語を使用して、sample_mflix.moviesコレクションから欠落値または null cast 値を持つドキュメントを検索します。

var isNullResult = session.createQuery("from Movie where cast is null", Movie.class)
.getResultList();
for (var m : isNullResult) {
System.out.println("Title: " + m.getTitle());
}
var isNullResult = entityManager.createQuery("select m from Movie m where m.cast is null", Movie.class)
.getResultList();
for (var m : isNullResult) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、先行する IS NULL 述語を次の $match ステージに変換します。これは、フィールドが明示的に null または欠落しているドキュメントに一致します。

{
"$match": {
"cast": { "$eq": null }
}
}

IS NOT NULL 述語は、null 以外または欠損値以外の値を持つフィールドを持つドキュメントに一致します。

次の例では、IS NOT NULL 述語を使用して、sample_mflix.moviesコレクションから directors 値を持つドキュメントを検索します。

var isNotNullResult = session.createQuery("from Movie where directors is not null", Movie.class)
.getResultList();
for (var m : isNotNullResult) {
System.out.println("Title: " + m.getTitle());
}
var isNotNullResultEm = entityManager.createQuery("select m from Movie m where m.directors is not null", Movie.class)
.getResultList();
for (var m : isNotNullResultEm) {
System.out.println("Title: " + m.getTitle());
}

Hibernetes ORM 拡張機能は、先行する IS NOT NULL 述語を次の $match ステージに変換します。これは、フィールドが存在し、明示的に null でないドキュメントに一致します。

{
"$match": {
"directors": { "$ne": null }
}
}

クエリ ステートメントでは次の演算子を使用して、複数のクエリ条件を組み合わせることができます。

  • and: すべての条件に一致する

  • or: 任意の条件に一致します

  • not: 条件に一致しません

次の例では、 sample_mflix.moviesコレクションから、title 値が "The Godfather" で、かつ year 値が 1972 であるドキュメントを検索します。

var logicalResult = session.createQuery("from Movie where title = :t and year = :y", Movie.class)
.setParameter("t", "The Godfather")
.setParameter("y", 1972)
.getSingleResult();
System.out.println("Title: " + logicalResult.getTitle());
var logicalResult = entityManager.createQuery("select m from Movie m where m.title = :t and m.year = :y", Movie.class)
.setParameter("t", "The Godfather")
.setParameter("y", 1972)
.getSingleResult();
System.out.println("Title: " + logicalResult.getTitle());

ObjectId 値に基づいてドキュメントを検索するには、セッションを使用している場合はこの値を get() メソッドに渡します。また、エンティティ マネージャーを使用している場合は find() メソッドに引数として渡します。 。

次の例では、sample_mflix.moviesコレクションからドキュメントをObjectId値で検索する。

var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));
var movieById = entityManager.find(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));

MongoDB埋め込みドキュメントを表現するには、@Struct 集計埋め込み可能ファイルを作成します。次に、 Hibernetes ORM 拡張機能を使用して、特定の親エンティティに関連付けられている @Struct の集計埋め込み可能ファイルを取得できます。

Tip

埋め込みドキュメントの表現の詳細については、 エンティティの作成ガイドの「埋め込みデータ」を参照してください。

次の例では、sample_mflix.moviesコレクションから title 値が "Hairspray" であるドキュメントを検索します。次に、コードは Awards @Struct 集計埋め込み可能を保存する awardsフィールドを取得し、Awards 埋め込み可能型の winsフィールドを出力します。

var embeddedResult = session.createQuery("select awards from Movie where title = :title", Awards.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var a : embeddedResult) {
System.out.println("Award wins: " + a.getWins());
}
var embeddedResult = entityManager.createQuery("select m.awards from Movie m where m.title = :title", Awards.class)
.setParameter("title", "Hairspray")
.getResultList();
for (var a : embeddedResult) {
System.out.println("Award wins: " + a.getWins());
}

HQL または JQL クエリの SELECT、WHERE、ORDER BY、および UPDATE 句でドット付きパス式を使用することで、埋め込み可能なタイプのフィールドを参照できます。パス式で複数の埋め込み可能名を連鎖させて、別の埋め込み可能内にネストされた埋め込み可能のフィールドを参照こともできます。

重要

クエリの制限

パス式は、カスタム読み取り式を定義するために @ColumnTransformer アノテーションを使用する埋め込み可能フィールドをサポートしていません。

Hibernetes ORM 拡張機能は、エンティティモデルを構築するときに、次の @Struct 集計埋め込み可能マッピングも拒否します。

  • @Idフィールドとして使用される @Struct 集計埋め込み可能

  • 多形 @Struct 集計埋め込み可能階層

これらのタイプのフィールドを参照ために、パス式を使用することはできません。

次の例では、パス式を使用して sample_mflix.moviesコレクション内のドキュメントをフィルタリングしています。 sample_mflix.moviesコレクションには 2 つの "Hairspray" 映画があります。 1 つの "Hairspray" 映画は 1998 から、もう 1 つは 2007 からの映画です。クエリでは、title の値が "Hairspray" で、かつ awards.wins の値が 10 より大きいドキュメントと一致します。

var matchingDocument = session.createQuery("from Movie where title = :title and awards.wins > :minWins", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("minWins", 10)
.getResultList();
for (var m : matchingDocument) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
var matchingDocument = entityManager.createQuery("select m from Movie m where m.title = :title and m.awards.wins > :minWins", Movie.class)
.setParameter("title", "Hairspray")
.setParameter("minWins", 10)
.getResultList();
for (var m : matchingDocument) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}

エンティティのフィールドに@Struct 集計埋め込み可能性の配列が保存されている場合、 サブクエリを使用して、その配列の少なくともEXISTS 1 つの要素が条件を満たす親ドキュメントを照合できます。 Hibernetes ORM 拡張機能はサブクエリをMongoDB $elemMatch 演算子に変換し、すべての条件を同じ配列要素に適用します。

注意

このセクションでは sample_restaurants データベースを使用

このセクションの例では、このガイドの他の場所で使用される sample_mflix.moviesコレクションではなく、sample_restaurants.restaurantsコレクションを使用します。

これらの例を実行するには、接続文字列のsample_restaurants データベースに接続します。sample_restaurants データベースの詳細については、 Atlasサンプルデータセット を参照してください。

次の Restaurant エンティティは restaurantsコレクションにマッピングされ、gradesフィールドに Grade 埋め込み可能ファイルのリストを保存します。

package org.example;
import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import jakarta.persistence.Column;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "restaurants")
public class Restaurant {
@Id
@ObjectIdGenerator
@Column(name = "_id")
private ObjectId id;
private String name;
private String borough;
private List<Grade> grades;
public Restaurant(String name, String borough, List<Grade> grades) {
this.name = name;
this.borough = borough;
this.grades = grades;
}
public Restaurant() {
}
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBorough() {
return borough;
}
public void setBorough(String borough) {
this.borough = borough;
}
public List<Grade> getGrades() {
return grades;
}
public void setGrades(List<Grade> grades) {
this.grades = grades;
}
}

次の Grade@Struct 集計埋め込み可能は、grades 配列の各要素を表します。

package org.example;
import jakarta.persistence.*;
import org.hibernate.annotations.Struct;
@Embeddable
@Struct(name = "Grade")
public class Grade {
private String grade;
private int score;
public Grade() {
}
public Grade(String grade, int score) {
this.grade = grade;
this.score = score;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}

Tip

埋め込み可能な配列の詳細については、 エンティティの作成ガイドの「 埋め込みデータ 」を参照してください。

restaurantsコレクション内のドキュメントは次のようになります。

{
"_id": { "$oid": "5eb3d668b31de5d588f4292a" },
"name": "Morris Park Bake Shop",
"borough": "Bronx",
"cuisine": "Bakery",
"grades": [
{ "date": { "$date": 1393804800000 }, "grade": "A", "score": 2 },
{ "date": { "$date": 1299715200000 }, "grade": "B", "score": 14 }
]
}

次の例では、 grade 値が "B" で、かつ score 値が 12 に等しい grades 配列要素が少なくとも 1 つあるレストランを検索します。どちらの条件も同じサブクエリに表示されるため、一致する配列要素は同じである必要があります。

var existsResult = session.createQuery(
"from Restaurant r where exists (select g.grade from r.grades g where g.grade = :grade and g.score = :score)",
Restaurant.class)
.setParameter("grade", "B")
.setParameter("score", 12)
.getResultList();
for (var r : existsResult) {
System.out.println("Name: " + r.getName());
}
var existsResultEm = entityManager.createQuery(
"select r from Restaurant r where exists (select g.grade from r.grades g where g.grade = :grade and g.score = :score)",
Restaurant.class)
.setParameter("grade", "B")
.setParameter("score", 12)
.getResultList();
for (var r : existsResultEm) {
System.out.println("Name: " + r.getName());
}

Hibernetes ORM 拡張機能は、前述の EXISTS サブクエリを次の $match ステージに変換します。

{
"$match": {
"grades": {
"$elemMatch": {
"grade": { "$eq": "B" },
"score": { "$eq": 12 }
}
}
}
}

Hibernetes ORM 拡張機能は、配列フィールドをクエリするための次の関数をサポートしています。

  • array_contains(): 配列フィールドに指定された値が含まれるドキュメントの一致

  • array_contains_nullable(): 配列フィールドに null 値を含む指定された値が含まれるドキュメントの一致

  • array_includes(): 配列フィールドに別の配列値が含まれるドキュメントの一致

  • array_includes_nullable(): 配列フィールドに、null 値を含む別の配列値が含まれるドキュメントの一致

Tip

配列関数の詳細については、 Hibernetes ORM ユーザーガイドの 配列を処理するための関数 を参照してください。

次の例では、array_contains() 関数を使用して、sample_mflix.moviesコレクションから cast 配列フィールドに値 "Kathryn Hahn" を持つドキュメントを検索する。

var arrayResult = session.createQuery("from Movie where array_contains(cast, :actor)", Movie.class)
.setParameter("actor", "Kathryn Hahn")
.getResultList();
for (var m : arrayResult) {
System.out.println("Title: " + m.getTitle());
}
var arrayResult = entityManager.createQuery("select m from Movie m where array_contains(m.cast, :actor)", Movie.class)
.setParameter("actor", "Kathryn Hahn")
.getResultList();
for (var m : arrayResult) {
System.out.println("Title: " + m.getTitle());
}

HQL クエリと JQL クエリで集計関数を使用して、クエリ結果をグループ化して要約したり、HAVING 句を使用してグループ化された結果をフィルタリングしたりできます。 HQL と JQL は次の集計関数をサポートしています。

  • count()

  • sum()

  • avg()

  • min()

  • max()

注意

要件でグループ化

集計関数には GROUP BY 句が必要です。結果をグループ化せずに集計関数を使用するクエリ(select count(*) from Movieなど)はまだサポートされていません。 SELECT 句内の非集計フィールドは、GROUP BY 句にも表示される必要があります。

次の例では、1920 から 1924 の間に公開された映画を年ごとにグループ化しています。各年について、映画の本数とすべての映画の合計実行時間を返します。 HAVING 句には、映画の合計ランタイムが 300 分を超える年のみが含まれ、結果が年ごとに並べられます。

var aggregateResult = session.createQuery(
"select year, count(*), sum(runtime) from Movie where year between 1920 and 1924 "
+ "group by year having sum(runtime) > 300 order by year",
Object[].class)
.getResultList();
for (var row : aggregateResult) {
System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Total runtime: " + row[2]);
}
var aggregateResult = entityManager.createQuery(
"select m.year, count(m), sum(m.runtime) from Movie m where m.year between 1920 and 1924 "
+ "group by m.year having sum(m.runtime) > 300 order by m.year",
Object[].class)
.getResultList();
for (var row : aggregateResult) {
System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Total runtime: " + row[2]);
}

MongoDBデータに対してその他の操作を行う方法の詳細については、CRUD 操作ガイドを参照してください。

関連付けによってリンクされているエンティティ全体をクエリする方法については、「 コレクション全体でエンティティを結合する 」ガイドを参照してください。

日時値の一部を返す方法、または日時値を string としてレンダリングする方法については、「 クエリでの日時関数の使用 」ガイドを参照してください。

HQL と JQL を使用してクエリを実行する方法の詳細については、非表示の ORM ドキュメントの「非表示のクエリ言語へのガイド」を参照してください。