Overview
このガイドでは、Hibernate ORM 用の MongoDB 拡張機能を使用して、MongoDB データベースでネイティブクエリを実行する方法を学ぶことができます。非表示クエリ言語 (HQL) または Java 永続クエリ言語 (JavaQL) の代わりに、ネイティブ クエリではMongoDBクエリ言語 (MQL) を使用してクエリを指定できます。MQL は、MongoDB のドキュメントベースのモデルと交流するために設計されたクエリ構文です。
Hibernate ORM の createQuery() メソッドは、一部のMongoDBクエリ機能をサポートしていません。createNativeQuery() メソッドを使用すると、MQLでデータベースクエリを指定し、Hibernate ORM 拡張機能の一部の運用上の制限をバイパスできます。
また、クエリ機能を拡張するために、MongoClientオブジェクトに対してクエリを直接実行することもできます。
サンプル データ
このガイドの例では、Atlasサンプルデータセットの sample_mflix.moviesコレクションを表す Movie エンティティを使用します。Movie エンティティには次の定義があります。
import com.mongodb.hibernate.annotations.ObjectIdGenerator; import org.bson.types.ObjectId; import java.util.List; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; public class Movie { private ObjectId id; private String title; private String plot; private int year; private int runtime; private List<String> cast; public Movie(String title, String plot, int year, int runtime, List<String> cast) { this.title = title; this.plot = plot; this.year = year; this.runtime = runtime; 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 int getRuntime() { return runtime; } public void setRuntime(int runtime) { this.runtime = runtime; } public List<String> getCast() { return cast; } public void setCast(List<String> cast) { this.cast = cast; } }
Hibernetes ORM 用のMongoDB拡張機能を使用してこのMongoDBサンプルコレクションと交流するJavaアプリケーションを作成する方法については、使い始めるチュートリアルを参照してください。
注意
永続性コンテキスト
Hibernate ORM を有効にしてデータベースと交流するには、Hibernate Session または Jakarta 永続性 EntityManager を使用して永続性コンテキスト内で操作を実行する必要があります。このガイドの例では、Session を使用しています。永続性コンテキストの詳細については、トランザクションとセッションのガイドを参照してください。
ネイティブクエリを実行する
ネイティブのMongoDBクエリを実行するには、クエリするコレクションとクエリ条件を集計パイプラインで含むMongoDBクエリ言語(MQL)ステートメントを指定します。
MQLステートメントは次の形式です。
String mqlSyntax = """ { aggregate: "<collection to query>", pipeline: [ <aggregation pipeline stages> ] } """;
重要
$ プロジェクトステージの要件
MQL ステートメントの集計パイプラインには$projectステージが含まれている必要があります。クエリ ドキュメントをエンティティ インスタンスとして返すには、$project ステージでプライマリキー フィールド以外の各エンティティ フィールドを指定する必要があります。
次に、MQL ステートメントを createNativeQuery() メソッドに渡します。パラメーター値を使用するネイティブクエリは実行できません。代わりに、MQLステートメント内で検索期間を指定します。
ネイティブクエリを使用して、次の操作を実行できます。
ドキュメント フィールドのフィルターとソート
この例ではMQLステートメントを createNativeQuery() メソッドに渡して、sample_mflix.moviesコレクションに対してネイティブクエリを実行します。このコードでは、次の集計パイプライン ステージを指定します。
$match: タイトルフィールドの値が のドキュメントをフィルター"The Parent Trap"$sort: 一致するドキュメントをyearフィールドで降順に並べ替えます$project:Movieエンティティで定義されている各ドキュメントフィールドを返します
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { title: { $eq: "The Parent Trap" } } }, { $sort: { year: -1 } }, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear()); }
Title: The Parent Trap, Year: 1998 Title: The Parent Trap, Year: 1961
算術演算子の使用
Hibernetes ORM 拡張機能は現在、算術演算子を使用する HQL または JQL ステートメントをサポートしていません。ただし、 MQLステートメントで MongoDB の算術演算子を使用して、データに対して算術操作を実行できます。
Tip
算術演算子
Hibernate と MongoDB 演算子の詳細については、次のリソースを参照してください。
次の例では、 sample_mflix.moviesコレクションに対して次のアクションを実行するネイティブ クエリを実行します。
yearの値が2000より大きく、かつruntimeフィールドが存在するドキュメントを検索するために、$matchステージを指定しますruntimeHoursという新しいフィールドを追加するには$addFieldsステージを指定します$divide算術演算子を使用して、新しいruntimeHoursフィールドのruntime値を 分から時間に変換しますプライマリキー フィールドを除く、
Movieエンティティで定義された各ドキュメントフィールドを返すには、$projectステージを指定します更新された各ドキュメントの
title値を出力します
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { year: { $gt: 2000 }, runtime: { $exists: true } } }, { $addFields: { runtimeHours: { $divide: [ "$runtime", 60 ] } }}, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1, runtimeHours: 1 }} ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Added field to movie: " + result.getTitle()); }
Added field to movie: Kate & Leopold Added field to movie: Crime and Punishment Added field to movie: Glitter Added field to movie: The Manson Family Added field to movie: The Dancer Upstairs Added field to movie: Fantastic Four ...
MongoDB 検索クエリを実行する
ネイティブ クエリを実行すると、データベースに対してMongoDB 検索クエリを実行することができます。これは、データに対するきめ細かなテキスト検索です。これらのクエリは、テキスト フレーズの一致、関連性の結果のスコアリング、一致の強調表示など、高度な検索機能を提供します。
重要
トランザクション内ではMongoDB 検索クエリを実行できません。
検索クエリを指定するには、クエリを実行するフィールドをカバーする検索インデックスを作成します。次に、$search または $searchMeta ステージを含む集計パイプラインをcreateNativeQuery() メソッドに渡します。
Tip
MongoDB Search
MongoDB Search クエリとインデックスの詳細については、 MongoDB Serverマニュアルの「 MongoDB Search の概要 」を参照してください。
この例では、$searchパイプラインステージをcreateNativeQuery()メソッドに渡して検索クエリを実行します。このコードは、次のアクションを実行します。
plotフィールドをカバーする検索インデックスを指定します。<indexName>プレースホルダーを 検索インデックス名に置き換えてください。plot値に対し、3単語以下の文字列"whirlwind romance"が含まれるドキュメントのクエリプライマリキー フィールドを除く、
Movieエンティティで定義された各ドキュメントフィールドを返すには、$projectステージを指定します一致するドキュメントの
titleとplotの値を出力します
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $search: { index: "<indexName>", phrase: { path: "plot", query: "whirlwind romance", slop: 3 } } }, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Title: " + result.getTitle() + ", Plot: " + result.getPlot()); }
Title: Tokyo Fiancèe, Plot: A young Japanophile Belgian woman in Tokyo falls into a whirlwind romance with a Francophile Japanese student. Title: Designing Woman, Plot: A sportswriter and a fashion-designer marry after a whirlwind romance, and discover they have little in common. Title: Vivacious Lady, Plot: On a quick trip to the city, young university professor Peter Morgan falls in love with nightclub performer Francey Brent and marries her after a whirlwind romance. But when he goes back ... Title: Ek Hasina Thi, Plot: A woman falls for a charming and mysterious businessman. The whirlwind romance turns sour when she is framed for his underworld crimes. Now, finally out of prison she is ready for sweet revenge. Title: Kick, Plot: An adrenaline junkie walks away from a whirlwind romance and embraces a new life as a thief, though he soon finds himself pursued by veteran police officer and engaged in a turf war with a local gangster. Title: A Tale of Winter, Plot: Felicie and Charles have a serious if whirlwind holiday romance. Due to a mix-up on addresses they lose contact, and five years later at Christmas-time Felicie is living with her mother in ...
MongoClient 操作を実行する
createQuery() メソッドも createNativeQuery() メソッドもサポートしていないデータベース操作を実行する場合は、Javaアプリケーションで直接 MongoClient オブジェクトを操作できます。MongoClient を使用すると、 MongoDB Java Sync Driver の 機能にアクセスできます。
Javaドライバーを使ってMongoDBと交流する方法を学ぶには、MongoDB Javaドライバーのドキュメントを参照してください。
MongoClient によるインデックスの作成
Hibernate ORM 拡張機能を使用してコレクションにインデックスを作成することはできませんが、MongoClient をインスタンス化してJavaドライバーの createIndex() メソッドを使用できます。次のコードを使用することで、sample_mflix.moviesコレクションに titleフィールドインデックスが作成されます。
// Replace the <connection URI> placeholder with your MongoDB connection URI String uri = "<connection URI>"; MongoClient mongoClient = MongoClients.create(uri); MongoDatabase db = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = db.getCollection("movies"); String indexResult = collection.createIndex(Indexes.ascending("title")); System.out.println(String.format("Index created: %s", indexResult));
Index created: title_1
Javaドライバーを使用してインデックスを作成する方法の詳細については、Javaドライバーのドキュメントのインデックスガイドを参照してください。
詳細情報
このガイドで説明されているクエリ言語の詳細については、次のリソースを参照してください。
非表示 ORM ドキュメントの「非表示クエリ言語のガイド」
MongoDB Serverマニュアルの MongoDBクエリ言語リファレンス