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

执行原生数据库查询

在本指南中,您可以学习如何使用MongoDB Extension for Hibernate ORM 在MongoDB 数据库上运行原生查询。原生查询允许您使用 MongoDB 查询语言 (MQL) 来指定查询,而不是使用 Hibernate Query Language (HQL) 或 Jakarta Persistence Query Language (JPQL)。MQL是一种查询语法,旨在与 MongoDB 基于文档的模型进行交互。

提示

最出色的特性

要学习有关 MQL 语法和功能的更多信息,请参阅 MongoDB 查询语言 参考,详见 MongoDB Server 手册。

Hibernate ORM 的 createQuery() 方法不支持某些MongoDB查询功能。createNativeQuery() 方法允许您在MQL中指定数据库查询并绕过 Hibernate ORM 扩展的某些操作限制。

您还可以直接对 MongoClient对象运行查询,以扩展查询功能。

The examples in this guide use the Movie entity, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie entity has the following definition:

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

要学习如何创建Java应用程序以使用MongoDB Extension for Hibernate ORM与此MongoDB示例集合交互,请参阅 入门教程

注意

持久性上下文

To enable Hibernate ORM to interact with the database, you must run operations inside a persistence context by using a Hibernate Session or a Jakarta Persistence EntityManager. The examples in this guide use a Session. To learn more about persistence contexts, see the Transactions and Sessions guide.

要运行原生 MongoDB 查询,请指定 MongoDB 查询语言 (MQL) 声明,其中包括要查询的集合以及聚合管道中的查询条件。

提示

聚合管道 (Aggregation Pipeline)

要学习有关构建聚合管道和运行聚合操作的更多信息,请参阅MongoDB Server手册中的聚合管道参考。

MQL声明采用以下格式:

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

重要

$ 项目阶段要求

MQL声明中的聚合管道必须包含$project阶段。要将查询文档作为实体实例返回,您必须在 $project 阶段指定除主键字段之外的每个实体字段。

然后,将MQL声明传递给 createNativeQuery() 方法。您无法运行使用参数值的原生查询。相反,请在MQL声明中指定搜索术语。

您可以使用原生查询来执行以下操作:

This example runs a native query on the sample_mflix.movies collection by passing an MQL statement to the createNativeQuery() method. The code specifies the following aggregation pipeline stages:

  • $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

Hibernate ORM 扩展当前不支持使用算术操作符的 HQL 或 JPQL 声明。但是,您可以在 MQL 声明中使用 MongoDB 的算术操作符对数据执行算术操作。

提示

算术操作符

The following example runs a native query on the sample_mflix.movies collection that performs the following actions:

  • 指定一个 $match 阶段,以匹配 year 值大于 2000runtime字段存在的文档

  • 指定 $addFields 阶段以添加名为 runtimeHours 的新字段

  • 对于新的 runtimeHours字段,使用 $divide 算术操作符将 runtime 值从分钟转换为小时

  • 指定一个 $project 阶段以返回 Movie 实体中定义的每个文档字段,但主键字段除外

  • 打印每个已更新文档的 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 搜索查询,这是对数据的细粒度文本搜索。这些查询提供高级搜索功能,例如匹配文本短语、对结果的相关性进行评分以及突出显示匹配项。

重要

您无法在ACID 事务中运行MongoDB 搜索查询。

要指定搜索查询,请创建涵盖要查询的字段的搜索索引。然后,将聚合管道传递给包含 $search$searchMeta 阶段的 createNativeQuery() 方法。

提示

MongoDB Search

要学习有关 MongoDB 搜索查询和索引的更多信息,请参阅 MongoDB Server 手册中的 MongoDB 搜索概述

This example runs a Search query by passing the $search pipeline stage to the createNativeQuery() method. The code performs the following actions:

  • 指定涵盖 plot字段的搜索索引。确保将 <indexName> 占位符替换为您的搜索索引名称。

  • 查询 plot 值包含字符串 "whirlwind romance" 且字符串之间的单词数不超过 3 个的文档

  • 指定一个 $project 阶段以返回 Movie 实体中定义的每个文档字段,但主键字段除外

  • 打印匹配文档的 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 的功能。

提示

功能支持

要了解必须使用 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驱动程序文档中的索引指南。

要进一步学习;了解本指南中讨论的查询语言,请参阅以下资源:

后退

指定查询

在此页面上