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

ネイティブデータベースクエリの実行

このガイドでは、Hibernate ORM用MongoDB拡張機能を使用して、MongoDBデータベースでネイティブクエリを実行する方法を学ぶことができます。Hibernate クエリ言語 (HQL) や Jakarta Persistence クエリ言語 (JPQL) の代わりに、ネイティブクエリを使用すると、MongoDB クエリ言語 (MQL) を使用してクエリを指定できます。MQLは、MongoDBのドキュメントベースのモデルと交流するために設計されたクエリ構文です。

Tip

MongoDB クエリ言語

MQL の構文と機能の詳細を学ぶには、 MongoDB Serverマニュアルの 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; @Entity@Table(name = "movies")public class Movie { @Id @ObjectIdGenerator private ObjectId id; private String title; private String plot; private int year; private int runtime; private List<String> cast; private List<String> directors; public Movie(String title, String plot, int year, int runtime, List<String> cast, List<String> directors) { this.title = title; this.plot = plot; this.year = year; this.runtime = runtime; this.cast = cast; this.directors = directors; } 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; } public List<String> getDirectors() { return directors; } public void setDirectors(List<String> directors) { this.directors = directors; }}

Hibernetes ORM 用のMongoDB拡張機能を使用してこのMongoDBサンプルコレクションと交流するJavaアプリケーションを作成する方法については、Get Started チュートリアルを参照してください。

注意

永続性コンテキスト

Hibernate ORM を有効にしてデータベースと交流するには、Hibernate Session または Jakarta 永続性 EntityManager を使用して永続性コンテキスト内で操作を実行する必要があります。このガイドの例では、Session を使用しています。永続性コンテキストの詳細については、トランザクションとセッションのガイドを参照してください。

ネイティブのMongoDBクエリを実行するには、クエリするコレクションとクエリ条件を集計パイプラインで含むMongoDBクエリ言語(MQL)ステートメントを指定します。

Tip

Aggregation Pipeline

集計パイプラインの構築と集計操作の実行中の詳細については、 MongoDB Serverマニュアルの集計パイプライン参照を参照してください。

MQLステートメントは次の形式です。

String mqlSyntax = """{ aggregate: "<collection to query>", pipeline: [ <aggregation pipeline stages> ]}""";

重要

$ プロジェクトステージの要件

MQLステートメントの集計パイプラインには、$projectステージを含める必要があります。クエリドキュメントをエンティティインスタンスとして返すには、_idフィールドを含め、$projectステージで各エンティティフィールドを指定する必要があります。Hibernate ORM拡張機能は、プロジェクトするフィールドを返し、省略した場合は_idを抑制します。_idを省略したエンティティバインドクエリは、エンティティ識別子が_idにマップされるため、Unknown column label [_id]で失敗する可能性があります。識別子を利用可能な状態に保つには、_id: 1をプロジェクトします。

そして、MQL ステートメントを createNativeQuery() メソッドに渡します。

ネイティブクエリを使用して、次の操作を実行できます。

重要

拡張 JSON 構文が必要

ネイティブクエリは、Extended JSON v2形式で書き込み (write)する必要があります。Hibernate ORM拡張機能は、ネイティブクエリでのシングルクォートやMongoDB Server shellの正規表現構文(/pattern/)をサポートしていません。たとえば、正規表現でクエリを実行するには、/pattern/の代わりに$regularExpression Extended JSON型を使用します。

この例では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: { _id: 1, 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());}

注意

ネイティブクエリは、Hibernate ORM拡張機能でサポートされていない算術操作に最適です。Hibernate ORM拡張機能がサポートする算術演算子の詳細については、機能互換性ページの「クエリサポート」セクションを参照してください。

次の例では、 sample_mflix.moviesコレクションに対して次のアクションを実行するネイティブ クエリを実行します。

  • year の値が 2000 より大きく、かつ runtimeフィールドが存在するドキュメントを検索するために、$match ステージを指定します

  • runtimeHours という新しいフィールドを追加するには $addFields ステージを指定します

  • $divide算術演算子を使用して、新しいruntimeHoursフィールドのruntime値を 分から時間に変換します

  • Movie エンティティで定義された各ドキュメントフィールドを返す $project ステージを指定します(_id フィールドを含む)。

  • 更新された各ドキュメントの title 値を出力します

String nativeQuery = """{ aggregate: "movies", pipeline: [ { $match: { year: { $gt: 2000 }, runtime: { $exists: true } } }, { $addFields: { runtimeHours: { $divide: [ "$runtime", 60 ] } }}, { $project: { _id: 1, 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());}

Tip

算術演算子

Hibernate と 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 ステージを指定します(_id フィールドを含む)。

  • 一致するドキュメントの title と plot の値を出力します

String nativeQuery = """{ aggregate: "movies", pipeline: [ { $search: { index: "<indexName>", phrase: { path: "plot", query: "whirlwind romance", slop: 3 } } }, { $project: { _id: 1, 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());}

MQL ステートメント内では、名前付きパラメータ (:name) または序数パラメータ (?1) を使用して値を指定できます。次の例では、title パラメーター値を名前付きパラメーターまたは序数パラメーターとして提供し、その後、setParameter() を使用してパラメーター値を提供する方法を示します。

String nativeQuery = """{ aggregate: "movies", pipeline: [ { $match: { title: { $eq: :movieTitle } } }, { $sort: { year: -1 } }, { $project: { _id: 1, title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ]}"""; var results = session.createNativeQuery(nativeQuery, Movie.class) .setParameter("movieTitle", "The Parent Trap") .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());}

createQuery() メソッドも createNativeQuery() メソッドもサポートしていないデータベース操作を実行する場合は、Javaアプリケーションで直接 MongoClient オブジェクトを操作できます。MongoClient を使用すると、 MongoDB Java Sync Driver の 機能にアクセスできます。

Tip

機能サポート

アクセスするには MongoClientオブジェクトを使用する必要があるサポートされていないMongoDB機能の詳細については、機能互換性ページをご覧ください。

Javaドライバーを使ってMongoDBと交流する方法を学ぶには、MongoDB Javaドライバーのドキュメントを参照してください。

Hibernate ORM 拡張機能を使用してコレクションにインデックスを作成することはできませんが、MongoClient をインスタンス化してJavaドライバーの createIndex() メソッドを使用できます。次のコードを使用することで、sample_mflix.moviesコレクションに titleフィールドインデックスが作成されます。

// Replace the <connection URI> placeholder with your MongoDB connection URIString 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));

Javaドライバーを使用してインデックスを作成する方法の詳細については、Javaドライバーのドキュメントのインデックスガイドを参照してください。

このガイドで説明されているクエリ言語の詳細については、次のリソースを参照してください。