MongoDB.local SF, Jan 15: See the speaker lineup & ship your AI vision faster. Use WEB50 to save 50%
Find out more >
Docs Menu
Docs Home
/ /

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

このガイドでは、Hibernate ORM 用の MongoDB 拡張機能を使用して、MongoDB データベースでネイティブクエリを実行する方法を学ぶことができます。非表示クエリ言語 (HQL) または Java 永続クエリ言語 (JavaQL) の代わりに、ネイティブ クエリでは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;
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)ステートメントを指定します。

Tip

Aggregation Pipeline

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

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 の算術演算子を使用して、データに対して算術操作を実行できます。

次の例では、 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 検索クエリを実行できません。

検索クエリを指定するには、クエリを実行するフィールドをカバーする検索インデックスを作成します。次に、$search または $searchMeta ステージを含む集計パイプラインをcreateNativeQuery() メソッドに渡します。

Tip

MongoDB Search

MongoDB Search クエリとインデックスの詳細については、 MongoDB Serverマニュアルの「 MongoDB Search の概要 」を参照してください。

この例では、$searchパイプラインステージをcreateNativeQuery()メソッドに渡して検索クエリを実行します。このコードは、次のアクションを実行します。

  • plotフィールドをカバーする検索インデックスを指定します。<indexName> プレースホルダーを 検索インデックス名に置き換えてください。

  • plot 値に対し、3 単語以下の文字列 "whirlwind romance" が含まれるドキュメントのクエリ

  • プライマリキー フィールドを除く、Movie エンティティで定義された各ドキュメントフィールドを返すには、$project ステージを指定します

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

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 ...

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 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ドライバーのドキュメントのインデックスガイドを参照してください。

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

戻る

クエリを指定する

項目一覧