Overview
In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to run native queries on your MongoDB database. Instead of Hibernate Query Language (HQL) or Jakarta Persistence Query Language (JPQL), native queries allow you to use MongoDB Query Language (MQL) to specify your query. MQL is a query syntax designed for interacting with MongoDB's document-based model.
Hibernetes ORM の createQuery() メソッドは、一部のMongoDBクエリ機能をサポートしていません。 createNativeQuery() メソッドを使用すると、 MQLでデータベースクエリを指定し、 Hibernetes ORM 拡張機能の一部の運用上の制限をバイパスできます。
また、クエリ機能を拡張するために、MongoClientオブジェクトに対してクエリを直接実行することもできます。
サンプル データ
このガイドの例では、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; public class Movie { private ObjectId id; private String title; private String plot; private int year; private int runtime; private String[] cast; public Movie(String title, String plot, int year, int runtime, 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 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.
ネイティブ クエリの実行
ネイティブの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
算術演算子
Hibernetes とMongoDB算術演算子の詳細については、次のリソースを参照してください。
Numeric arithmetic in the Hibernate ORM query guide
MongoDB Serverマニュアルの「 算術演算子 」
次の例では、 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 }} ] } """; 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 Search クエリの実行
ネイティブ クエリを実行すると、データベースに対してMongoDB Search クエリを実行できます。これは、データに対するきめ細かなテキスト検索です。これらのクエリは、テキスト フレーズの一致、関連性の結果のスコアリング、一致の強調表示など、高度な検索機能を提供します。
重要
トランザクション内ではMongoDB Search クエリを実行できません。
検索クエリを指定するには、クエリを実行するフィールドをカバーする検索インデックスを作成します。次に、$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 の 機能にアクセスできます。
Tip
機能サポート
アクセスするには オブジェクトを使用する必要がある、サポートされていないMongoDB機能の詳細については、「MongoClient Hibernetes ORM 機能の互換性 」ページを参照してください。
Javaドライバーを使用してMongoDBを操作する方法については、 MongoDB Javaドライバーのドキュメント を参照してください。
MongoClient によるインデックスの作成
Hibernetes 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クエリ言語リファレンス 」