Docs Menu
Docs Home
/ /

クエリを指定する

In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to specify a database query.

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

Tip

To learn more about HQL and JPQL syntax, see A Guide to Hibernate Query Language in the Hibernate ORM documentation.

注意

クエリ サポート

The MongoDB Extension for Hibernate ORM does not support all MongoDB and Hibernate query features. To learn more, see Query Support on the Feature Compatibility page.

このガイドの例では、AtlasサンプルデータセットのMovie sample_mflix.moviesコレクションを表す エンティティを使用します。Movie エンティティには次の定義があります。

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
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 String[] cast;
public Movie(String title, String plot, int year, String[] cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
}
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 String[] getCast() {
return cast;
}
public void setCast(String[] cast) {
this.cast = cast;
}
}

To learn how to create a Java application that uses the MongoDB Extension for Hibernate ORM to interact with this MongoDB sample collection, see the Get Started tutorial.

重要

永続性コンテキスト

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();

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

// 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;

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

MongoDBデータをクエリするには、セッションまたはエンティティ マネージャーで createQuery() メソッドを呼び出します。次に、非表示クエリ言語(HQL)または Java 永続クエリ言語(JQL)のステートメントで一致する条件を指定します。

このセクションでは、次のクエリ操作を実行する方法について説明します。

コレクションからすべてのドキュメントを検索するには、基本的な 選択ステートメント を createQuery() メソッドに渡します。このステートメントでは、クエリするコレクションを表すエンティティを指定します。

次の例では、 Movie エンティティをクエリして、sample_mflix.moviesコレクションからすべてのドキュメントの title 値を検索します。

var allDocs = session.createQuery("select title from Movie", String.class)
.getResultList();
for (var t : allDocs) {
System.out.println("Title: " + t);
}
Title: A Corner in Wheat
Title: Gertie the Dinosaur
Title: The Perils of Pauline
Title: Civilization
Title: Where Are My Children?
...
var allDocs = entityManager.createQuery("select m.title from Movie m", String.class)
.getResultList();
for (var t : allDocs) {
System.out.println("Title: " + t);
}
Title: A Corner in Wheat
Title: Gertie the Dinosaur
Title: The Perils of Pauline
Title: Civilization
Title: Where Are My Children?
...

特定の条件に一致するドキュメントを検索するには、where 句を含む選択ステートメントを createQuery() メソッドに渡します。このステートメントでは、クエリするコレクションと一致する条件を表すエンティティを指定します。

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

var matchingDocs = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Romeo and Juliet")
.getResultList();
for (var m : matchingDocs) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Romeo and Juliet, Year: 1936
Title: Romeo and Juliet, Year: 1968
var matchingDocs = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class)
.setParameter("t", "Romeo and Juliet")
.getResultList();
for (var m : matchingDocs) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Romeo and Juliet, Year: 1936
Title: Romeo and Juliet, Year: 1968

特定の条件に一致する単一のドキュメントを取得するには、getSingleResult() メソッドを createQuery() メソッドにチェーンします。

次の例では、 sample_mflix.moviesコレクションから、title 値が "Best in Show" である単一のドキュメントを取得します。

var singleResult = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Best in Show")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000
var singleResult = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class)
.setParameter("t", "Best in Show")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
Title: Best in Show, Year: 2000

重要

nonUniqueResultException エラー

クエリが複数のドキュメントに一致する場合、getSingleResult() メソッドはNonUniqueResultException エラーをスローします。このエラーを回避するには、クエリが 1 つのドキュメントのみと一致することを確認するか、クエリ結果を 1 つのドキュメントに制限します。

HQL または JQL ステートメントを使用してクエリフィルターを作成する代わりに、Java 永続化基準API を使用して型安全性のあるクエリをプログラムで構築できます。

Criteria API を使用してクエリを作成するには、次のアクションを実行します。

  1. セッションまたはエンティティ マネージャーから CriteriaBuilderオブジェクトを作成します。

  2. ビルダから CriteriaQueryオブジェクトを作成し、クエリするエンティティを指定します。

  3. クエリ条件を指定するには、CriteriaQueryクラスが提供するクエリメソッドを使用します。

Tip

Criteria APIの詳細については、Java JIRA ドキュメントの「 Criteria API を使用してクエリを作成する 」を参照してください。

次の例では、 Criteria API を使用して、sample_mflix.moviesコレクションから year 値が 1925 であるすべてのドキュメントを検索します。

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Movie> movieRoot = cq.from(Movie.class);
cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925));
session.createQuery(cq).getResultList()
.forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan
Clash of the Wolves
Grass: A Nation's Battle for Life
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Movie> movieRoot = cq.from(Movie.class);
cq.select(movieRoot).where(cb.equal(movieRoot.get("year"), 1925));
entityManager.createQuery(cq).getResultList()
.forEach(m -> System.out.println(m.getTitle()));
Lady Windermere's Fan
Clash of the Wolves
Grass: A Nation's Battle for Life

現在 Hibernetes ORM 拡張機能でサポートされていないMongoDBクエリを実行するには、クエリをMongoDBクエリ言語(MQL)ステートメントとして createNativeQuery() メソッドに渡します。

ネイティブクエリの実行方法については、「 ネイティブクエリの実行 」ガイドを参照してください。

このセクションでは、演算子を使用して次のタイプのクエリフィルターを作成する方法について説明します。

Tip

このセクションでは、使用可能なすべてのクエリ演算子について説明するわけではありません。クエリ演算子の完全なリストを表示するには、 Hibernetes ORM クエリガイドの「 演算子式 」を参照してください。

注意

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

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

  • =: 等価一致

  • <>: 等価一致

  • >: 比較より大きい

  • >=: 以上の比較

  • <: 比較より小さい

  • <=: 以下の比較

次の例では、 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());
}
Title: Jurassic World
Title: The Stanford Prison Experiment
Title: Ex Machina
Title: Ant-Man
Title: The Danish Girl
Title: The Wedding Ringer
Title: Good Ol' Boy
Title: A Tale of Love and Darkness
Title: Aloha
...
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());
}
Title: Jurassic World
Title: The Stanford Prison Experiment
Title: Ex Machina
Title: Ant-Man
Title: The Danish Girl
Title: The Wedding Ringer
Title: Good Ol' Boy
Title: A Tale of Love and Darkness
Title: Aloha
...

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

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

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

  • not: Invert criteria

次の例では、 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());
Title: The Godfather
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());
Title: The Godfather

このセクションでは、クエリ結果を次の方法で変更する方法について説明します。

クエリ ステートメントで order by 句を使用すると、指定したフィールドの値でクエリ結果をソートできます。デフォルトでは 、order by 句はドキュメントを昇順でソートします。ドキュメントを降順で並べ替えるには、フィールド名に desc キーワードを追加します。

次の例では、 sample_mflix.moviesコレクションから一致するドキュメントを検索し、yearフィールドで降順に並べ替えます。

var sortResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
for (var m : sortResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950
var sortResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
for (var m : sortResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950

setFirstResult() メソッドをクエリに連結することで、クエリ結果内の指定した数のドキュメントをスキップできます。スキップする初期ドキュメントの数をこのメソッドの引数として渡します。

次の例では、前の例と同じクエリを実行しますが、結果内の最初の一致するドキュメントをスキップします。

var skipResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.setFirstResult(1)
.getResultList();
for (var m : skipResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950
var skipResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.setFirstResult(1)
.getResultList();
for (var m : skipResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 1997
Title: Cinderella, Year: 1950

クエリが返すドキュメント数を制限するには、setMaxResults() メソッドをクエリに連結します。返されるドキュメントの最大数をこのメソッドの引数として渡します。

次の例では、ソートの例と同じクエリを実行しますが、結果には一致するドキュメントが最大 2 つ返されます。

var limitResult = session.createQuery("from Movie where title = :t order by year desc", Movie.class)
.setParameter("t", "Cinderella")
.setMaxResults(2)
.getResultList();
for (var m : limitResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997
var limitResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc", Movie.class)
.setParameter("t", "Cinderella")
.setMaxResults(2)
.getResultList();
for (var m : limitResult) {
System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());
}
Title: Cinderella, Year: 2015
Title: Cinderella, Year: 1997

あるいは、次のコードに示すように、HQL または JQL のステートメントで limit 句を使用して、クエリが返すドキュメントの数を制限することもできます。

var limitClauseResult = session.createQuery("from Movie where title = :t order by year desc limit 2", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();
var limitClauseResult = entityManager.createQuery("select m from Movie m where m.title = :t order by m.year desc limit 2", Movie.class)
.setParameter("t", "Cinderella")
.getResultList();

このセクションでは、次のフィールドでクエリを実行する方法について説明します。

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 集計埋め込み可能値を取得できます。

重要

クエリの制限

埋め込み可能ファイルのクエリ制限の詳細については、 機能の互換性 ページの 「非表示のクエリ サポート」 を参照してください。

次の例では、 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());
}
Award wins: 0
Award wins: 21
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());
}
Award wins: 0
Award wins: 21

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());
}
Title: How to Lose a Guy in 10 Days
Title: The Secret Life of Walter Mitty
Title: Bad Words
Title: Afternoon Delight
Title: The D Train
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());
}
Title: How to Lose a Guy in 10 Days
Title: The Secret Life of Walter Mitty
Title: Bad Words
Title: Afternoon Delight
Title: The D Train

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

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

戻る

CRUD 操作