AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.

쿼리 지정

이 가이드 에서는 최대 절전 모드 ORM용 MongoDB 확장을 사용하여 데이터베이스 쿼리 지정하는 방법을 학습 수 있습니다.

쿼리 필터하다 만들어 쿼리 반환하는 문서 설정하다 를 구체화할 수 있습니다. 쿼리 필터하다 는 MongoDB 읽기 또는 쓰기 (write) 작업에서 문서를 일치시키는 데 사용하는 검색 기준을 지정하는 표현식 입니다. MongoDB 쿼리 필터를 만들려면 하이버네이트 쿼리 언어(HQL) 또는 자카르타 지속성 쿼리 언어(JPQL) 성명서를 사용합니다.

팁

HQL 및 JPQL 구문에 대해 자세히 학습하려면 하이버네이트 ORM 문서의 하이버네이트 쿼리 언어 가이드 를 참조하세요.

참고

쿼리 지원

최대 절전 모드 ORM용 MongoDB 확장은 모든 MongoDB 및 최대 절전 쿼리 기능을 지원 하지 않습니다. 자세히 학습 기능 호환성 페이지의 쿼리 지원을 참조하세요.

이 가이드 의 예제에서는 Atlas 샘플 데이터 세트의 sample_mflix.movies 컬렉션 나타내는 Movie 엔터티를 사용합니다. Movie 엔터티의 정의는 다음과 같습니다.

import com.mongodb.hibernate.annotations.ObjectIdGenerator;import org.bson.types.ObjectId;import java.time.Instant;import java.util.List;import jakarta.persistence.Embedded; import jakarta.persistence.Entity;import jakarta.persistence.FetchType;import jakarta.persistence.Id;import jakarta.persistence.OneToMany;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 List<String> cast; private List<String> directors; private Instant released; @Embedded private Awards awards; @OneToMany(mappedBy = "movie", fetch = FetchType.LAZY) private List<Comment> comments; public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) { this.title = title; this.plot = plot; this.year = year; this.cast = cast; this.directors = directors; this.released = released; this.awards = awards; } 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 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; } public Awards getAwards() { return awards; } public void setAwards(Awards awards) { this.awards = awards; } public Instant getReleased() { return released; } public void setReleased(Instant released) { this.released = released; } public List<Comment> getComments() { return comments; } public void setComments(List<Comment> comments) { this.comments = comments; }}

최대 절전 모드용 MongoDB 확장 ORM을 사용하여 이 MongoDB 샘플 컬렉션과 상호 작용하는 Java 애플리케이션 만드는 방법을 학습하려면 시작하기 튜토리얼을 참조하세요.

이 페이지의 코드 예시 에서는 다음 Awards @Struct 임베딩 가능 애그리게이션도 사용합니다.

@Embeddable@Struct(name = "Awards")public class Awards { private int wins; private int nominations; private String text; public Awards(int wins, int nominations, String text) { this.wins = wins; this.nominations = nominations; this.text = text; } public Awards() { } public int getWins() { return wins; } public void setWins(int wins) { this.wins = wins; } public int getNominations() { return nominations; } public void setNominations(int nominations) { this.nominations = nominations; } public String getText() { return text; } public void setText(String text) { this.text = text; }}

중요

지속성 컨텍스트

하이버네이트 ORM이 데이터베이스 와 상호 작용 활성화 하려면 하이버네이트 Session 또는 자카르타 퍼시스턴스 EntityManager를 사용하여 퍼시스턴스 컨텍스트 내에서 작업을 실행 해야 합니다. HQL을 사용하여 세션 쿼리를 정의하고 JPQL을 사용하여 엔터티 관리자 쿼리를 정의합니다.

이 가이드 의 예제를 실행 전에 다음 코드와 유사한 지속성 컨텍스트 및 트랜잭션 관리 코드를 애플리케이션 에 추가해야 합니다.

var sf = HibernateUtil.getSessionFactory();Session session = sf.openSession();Transaction tx = session.beginTransaction(); // ... Perform CRUD operations here tx.commit();session.close();sf.close();

세션을 사용하려면 SessionFactory를 구성하는 HibernateUtil.java 파일 만들어야 합니다. 자세히 학습 시작하기 튜토리얼의 애플리케이션 구성 단계를 참조하세요.

SessionFactory 인스턴스를 생성하려면 com.mongodb.hibernate.semantics.nulls 구성 속성을 MQL(으)로 설정해야 합니다. 이 속성은 필수이며 기본값이 없고 현재 다른 값을 허용하지 않습니다. 속성을 생략하거나 다른 값으로 설정하면 Hibernate ORM 확장이 HibernateException을(를) throw합니다.

com.mongodb.hibernate.semantics.nulls을(를) MQL(으)로 설정하면, 이 속성은 null 관련 동작이 SQL null 의미 체계에 의해 정의된 3값 논리가 아니라 Hibernate ORM 확장이 변환 중에 생성하는 MongoDB 쿼리 언어(MQL)를 따른다는 것을 선언합니다.

Hibernate ORM 확장이 특정 변환을 보장하지 않으므로 null 관련 동작의 결과는 릴리스마다 변경될 수 있습니다.

다음 예시는 hibernate.properties 파일에서 com.mongodb.hibernate.semantics.nulls 속성을 설정합니다.

com.mongodb.hibernate.semantics.nulls=MQL

쿼리 문에서 다음 연산자를 사용하여 필드 값을 지정된 쿼리 값과 비교할 수 있습니다.

  • =: 동등성 매칭

  • <>: 부등호 일치

  • >: 비교보다 큼

  • >=: 크거나 같은 비교

  • <: 비교보다 작음

  • <=: 보다 작거나 같은 비교

다음 예시 sample_mflix.movies 컬렉션 에서 year 값이 2015 보다 크거나 같은 문서를 검색합니다.

var comparisonResult = session.createQuery("from Movie where year >= :y", Movie.class) .setParameter("y", 2015) .getResultList();for (var m : comparisonResult) { System.out.println("Title: " + m.getTitle());}

행 값 조건자(row-value predicate)는 단일 표현식에서 괄호로 묶인 필드 목록을 괄호로 묶인 값 목록과 비교합니다. Hibernate ORM 확장은 다음 연산자를 사용하는 행 값 조건자를 지원합니다.

  • =: 동등성 매칭

  • <>: 부등호 일치

  • IN 및 NOT IN: 값 행 목록과 일치

값을 바인딩된 매개변수나 리터럴로 제공할 수 있으며, 각 목록에는 동일한 수의 구성 요소가 포함되어야 합니다.

다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "Jurassic World" 이고 year 값이 2015 인 문서 조회합니다.

var rowValueResult = session.createQuery("from Movie where (title, year) = (:t, :y)", Movie.class) .setParameter("t", "Jurassic World") .setParameter("y", 2015) .getResultList();for (var m : rowValueResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 각 구성 요소 쌍을 별도로 비교합니다. 이전 행 값 조건자는 다음 $match 단계로 변환됩니다.

{ "$match": { "$and": [ { "title": { "$eq": "Jurassic World" } }, { "year": { "$eq": 2015 } } ] }}

<> 연산자를 사용하는 행 값 조건자는 $nor 표현식으로 래핑된 동일한 $and 표현식으로 변환됩니다.

where (title1, year1) = (title2, year2)에서와 같이 필드를 다른 필드 목록과 비교하면 Hibernate ORM 확장은 술어를 $expr 표현식으로 대신 변환합니다.

SELECT 절에서 행 값 조건자를 사용할 수 있습니다. 조건자는 프로젝션에서 불리언 값으로 평가됩니다.

참고

Null 의미 체계

행 값 술어는 Hibernate ORM의 3항 논리보다는 MongoDB 쿼리 언어의 null 의미 체계를 따릅니다. 따라서 <> 술어는 구성 요소가 null이거나 누락된 문서를 찾습니다. 더 자세히 알아보려면 이 가이드의 필드 값을 Null과 비교 섹션을 참조하세요.

필드 한 행을 여러 행의 값에 대해 일치시키려면 IN 연산자를 사용합니다. 다음 예시에서는 두 개의 title 및 year 쌍 중 하나와 일치하는 문서를 조회합니다.

var rowValueInResult = session.createQuery( "from Movie where (title, year) in (('Jurassic World', 2015), ('Ex Machina', 2015))", Movie.class) .getResultList();for (var m : rowValueInResult) { System.out.println("Title: " + m.getTitle());}

앞선 행 값 조건은 다음 $match 단계로 변환됩니다.

{ "$match": { "$or": [ { "$and": [ { "title": { "$eq": "Jurassic World" } }, { "year": { "$eq": 2015 } } ] }, { "$and": [ { "title": { "$eq": "Ex Machina" } }, { "year": { "$eq": 2015 } } ] } ] }}

목록에 값 행이 하나만 포함되어 있으면 조건자는 $and 표현식으로만 변환됩니다. NOT IN 조건자는 $nor 표현식으로 래핑된 $or 표현식으로 변환됩니다.

중요

정렬 비교

Hibernate ORM 확장은 >, >=, < 또는 <= 연산자를 사용하는 행 값 조건자를 지원하지 않습니다. 이러한 조건자로 인해 Hibernate ORM 확장이 FeatureNotSupportedException을(를) 발생시킵니다.

비교 연산자를 사용하여 필드를 null와 비교할 때, Hibernate ORM 확장은 Hibernate ORM이 정의하는 3항 논리 대신 MongoDB 쿼리 언어 null 의미 체계를 적용합니다.

참고

null에 대한 Hibernate 3진 논리(Ternary Logic)

Hibernate ORM v6.3 이상에서는 null 와의 비교를 null으로 평가하며, 술어는 이를 false로 처리합니다. Hibernate ORM 확장은 이 동작을 구현하지 않습니다. Hibernate ORM 확장이 지원하는 기능에 대해 자세히 알아보려면 기능 호환성 페이지의 데이터 유형 지원을 참조하세요.

MongoDB 비교 연산자는 누락된 필드와 명시적인 null 값을 저장하는 필드 모두를 null(으)로 평가합니다. 그 결과, = null 비교는 필드에 null이 저장되어 있는 문서와 필드가 없는 문서를 일치시킵니다. <> null 또는 != null 비교는 필드가 다른 값을 저장하는 문서와 일치합니다.

다음 예시 = 연산자를 사용하여 sample_mflix.movies 컬렉션에서 null 값이 있거나 cast 값이 누락된 문서를 조회합니다.

var nullComparisonResult = session.createQuery("from Movie where cast = null", Movie.class) .getResultList();for (var m : nullComparisonResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이 쿼리를 다음 $match 단계로 변환합니다.

{ "$match": { "cast": { "$eq": null } }}

>, >=, <, <= 연산자를 사용하는 비교는 존재하지 않는 필드에 대해 MongoDB BSON 비교 순서를 따릅니다. null은 고유한 BSON 유형이므로 >= null 또는 <= null 비교는 필드가 null을 저장하거나 누락된 문서를 일치시킵니다. > null 또는 < null 비교는 일치하는 문서가 없습니다.

비교 연산자 대신 술어를 사용하여 null 및 누락된 값을 일치시키려면 이 가이드의 IS NULL 및 IS NOT NULL 섹션을 참조하세요.

필드 값, 리터럴, 쿼리 매개변수에서 값을 계산할 수 있습니다. 그런 다음 SELECT 절에서 해당 값을 반환하거나 WHERE 절에서 비교할 수 있습니다. Hibernate ORM 확장은 계산된 표현식을 MongoDB 집계 표현식으로 변환합니다.

Hibernate ORM 확장은 계산된 표현식에서 다음 산술 연산자를 지원합니다.

  • +: 덧셈, 다음으로 변환됨 $add

  • -: 뺄셈(다음으로 변환됨) $subtract

  • *: 곱셈, ~ub85c 변환됩니다. $multiply

  • /: Division으로 번역되며, $divide

  • 단항 - 및 +

참고

나눗셈은 항상 정수를 반환합니다

Hibernate ORM은 MongoDB 집계 파이프라인의 나눗셈을 항상 double을 반환하는 MongoDB $divide 연산자로 변환합니다. Hibernate ORM 확장은 $divide을 $toInt로 래핑하여 결과를 자르거나, 결과 유형이 BIGINT인 경우 $toLong으로 자릅니다. 이 동작은 Hibernate ORM PORTABLE_INTEGER_DIVISION 설정을 활성화했는지 여부에 관계없이 / 연산자 및 Criteria API quot() 메서드에 적용됩니다.

div 연산자는 지원되지 않습니다.

비교 연산자 사용 섹션에 설명된 비교 연산자를 계산된 표현식 내에서 사용할 수도 있습니다.

중요

피연산자 제한 사항

계산된 표현식의 피연산자는 필드 참조, 리터럴 또는 쿼리 매개변수여야 합니다. Hibernate ORM 확장은 피연산자로 함수 호출을 지원하지 않습니다.

Hibernate ORM은 HQL % 연산자를 mod() 함수 호출로 다시 작성하므로 %도 지원되지 않습니다. 모듈로 연산을 수행하려면 Criteria API CriteriaBuilder.mod() 메서드를 사용하세요. 이 메서드는 MongoDB $mod 연산자로 변환됩니다.

Criteria API CriteriaBuilder.quot() 메서드는 / 연산자와 동일하게 작동합니다.

계산된 표현식을 선택하면 Hibernate ORM 확장이 $project 단계에 계산된 값을 추가합니다. AS 키워드를 사용하여 표현식에 별칭을 할당하면 Hibernate ORM 확장이 해당 별칭을 프로젝션 키로 사용합니다. 그렇지 않으면 #c_<n> 형식으로 키를 생성합니다.

다음 예시는 sample_mflix.movies 컬렉션에 있는 각 "Hairspray" 영화의 연령을 쿼리 매개변수에서 year 필드 값을 빼서 계산합니다.

var arithmeticResult = session.createQuery( "select title, :currentYear - year as age from Movie where title = :title", Object[].class) .setParameter("currentYear", 2026) .setParameter("title", "Hairspray") .getResultList();for (var row : arithmeticResult) { System.out.println("Title: " + row[0] + ", Age: " + row[1]);}

Hibernate ORM 확장은 앞서 언급한 계산된 표현식을 다음 $project 단계로 변환합니다.

{ "$project": { "title": true, "age": { "$subtract": [ 2026, "$year" ] }, "_id": 0 }}

WHERE 절에서는 계산된 표현식을 값과 비교하거나 두 필드 값을 서로 비교할 수 있습니다. 비교의 어느 한쪽이 직접적인 필드 참조나 값이 아닌 경우, Hibernate ORM 확장은 비교를 MongoDB $expr 연산자로 래핑합니다. 필드와 값 간의 비교는 계속해서 간결한 { field: { operator: value } } 형식을 사용합니다.

다음 예시는 2026보다 20 년 미만으로 일찍 개봉된 "Hairspray" 편의 영화를 조회합니다.

var computedFilterResult = session.createQuery( "from Movie where title = :title and :currentYear - year < 20", Movie.class) .setParameter("title", "Hairspray") .setParameter("currentYear", 2026) .getResultList();for (var m : computedFilterResult) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());}

Hibernate ORM 확장은 앞선 쿼리를 다음 $match 단계로 변환하며, 여기서 title 비교는 간소화된 형식을 사용하고 계산된 비교는 $expr를 사용합니다.

{ "$match": { "$and": [ { "title": { "$eq": "Hairspray" } }, { "$expr": { "$lt": [ { "$subtract": [ 2026, "$year" ] }, 20 ] } } ] }}

SELECT 성명서에서 비교를 사용하여 필터로 사용하는 대신 불리언 결과를 반환할 수 있습니다.

다음 예시는 각 "Hairspray" 영화의 제목과 해당 영화가 2000 이후에 개봉되었는지 여부를 반환합니다.

var comparisonResult = session.createQuery( "select title, year > 2000 as isRecent from Movie where title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList();for (var row : comparisonResult) { System.out.println("Title: " + row[0] + ", Recent: " + row[1]);}

Hibernate ORM 확장은 앞선 비교를 다음 $project 단계로 변환합니다.

{ "$project": { "title": true, "isRecent": { "$gt": [ "$year", 2000 ] }, "_id": 0 }}

CASE 표현식은 지정한 각 조건에 대해 서로 다른 값을 반환합니다. Hibernate ORM 확장은 HQL 및 JPQL 단순 및 검색된 CASE 표현식을 모두 지원합니다.

  • 단순 case: CASE 키워드 뒤의 표현식은 각 WHEN 절의 값과 동일한지 비교됩니다. 단순 case 표현식의 예는 case year when 2000 then 'Modern' else 'Classic' end입니다.

  • 검색된 케이스: 각 WHEN 절은 술어를 지정합니다. 검색된 케이스 표현식의 예시는 case when year > 2000 then 'Modern' else 'Classic' end입니다.

Hibernate ORM 확장은 CASE 표현식을 MongoDB $switch 연산자로 변환합니다. 이 연산자는 각 WHEN 절에 대한 분기를 생성하고 지정한 순서대로 분기를 평가합니다. ELSE 절은 $switch의 default 값이 됩니다. ELSE 절을 생략하면 일치하는 분기가 없을 때 표현식이 null를 반환합니다.

CASE 표현식은 계산된 표현식을 반환할 수 있으며, 다음 위치에서 CASE 표현식을 사용할 수 있습니다.

  • 다음 예시와 같이 SELECT 절입니다.

  • WHERE 절의 비교 피연산자이며, Hibernate ORM 확장은 이를 MongoDB $expr 연산자로 래핑합니다.

  • 대량 업데이트 성명서의 SET 절입니다. 예시를 보려면 CRUD 작업 가이드의 조건부 논리에 기반한 다중 업데이트 예시 섹션을 참조하세요.

다음 예시는 각 "Hairspray" 영화의 제목과 영화의 year 값에 따라 달라지는 레이블을 반환합니다.

var caseResult = session.createQuery( "select title, case when year > 2000 then 'Modern' else 'Classic' end as era " + "from Movie where title = :title", Object[].class) .setParameter("title", "Hairspray") .getResultList();for (var row : caseResult) { System.out.println("Title: " + row[0] + ", Era: " + row[1]);}

Hibernate ORM 확장은 앞의 CASE 표현식을 다음 $project 단계로 변환합니다.

{ "$project": { "title": true, "era": { "$switch": { "branches": [ { "case": { "$gt": [ "$year", 2000 ] }, "then": "Modern" } ], "default": "Classic" } }, "_id": 0 }}

중요

CASE 표현식 제한 사항

CASE 표현식은 MongoDB 집계 표현식을 생성하므로 필드 참조나 리터럴 값이 필요한 위치에서는 사용할 수 없습니다. CASE 표현식을 사용하면 Hibernate ORM 확장에서 FeatureNotSupportedException을(를) 발생시킵니다.

  • ORDER BY 절에서 동일한 CASE 표현식이 GROUP BY 키인 경우는 예외입니다.

  • LIKE 술어의 표현식으로 사용됩니다.

  • IN 또는 IS NULL 조건자의 테스트 표현식으로 사용됩니다.

  • 피연산자가 아닌 WHERE 절 조건자로 사용됩니다.

하이버네이트 ORM 확장은 쿼리 성명서에서 다음 술어 비교 연산자를 지원합니다.

참고

Hibernate ORM 확장은 모든 비교 연산자를 지원하지 않습니다. 지원 제한 사항에 대해 자세히 알아보려면 기능 호환성 페이지의 쿼리 지원 을 참조하세요.

EXISTS 술어는 특정 필드가 있는 문서를 일치시키고, 일치하는 배열 요소의 수에 관계없이 일치하는 각 상위 문서에 대해 하나의 결과만 반환합니다.

참고

EXISTS 하위 쿼리 제한 사항

Hibernate ORM 확장은 부모 엔티티의 배열 필드에 대해서만, 그리고 WHERE 절에서만 EXISTS 하위 쿼리를 지원합니다. Hibernate ORM 확장은 다음 EXISTS 하위 쿼리를 지원하지 않습니다.

  • 필드를 먼저 지정하지 않고 엔터티에 대해 쿼리

  • 동일한 상위 문서의 필드 비교

  • SELECT 절에 나타남

완전한 예시는 이 가이드의 내장 배열의 요소에 대한 쿼리 섹션을 참조하십시오.

BETWEEN 술어는 지정된 범위 내의 필드 값을 가진 문서를 일치시킵니다.

다음 예시는 BETWEEN 예측자를 사용하여 sample_mflix.movies 컬렉션에서 2012부터 2013까지의 year 값을 가진 문서를 조회합니다. (인클루시브)

var betweenResult = session.createQuery("from Movie where year between :start and :end", Movie.class) .setParameter("start", 2012) .setParameter("end", 2013) .getResultList();for (var m : betweenResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 BETWEEN 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "year": { "$gte": 2012, "$lte": 2013 } }}

IN 조건자는 필드 값이 지정된 목록의 값과 일치하는 문서를 찾습니다. 리터럴, 명명된 매개변수 또는 위치 매개변수로 목록 값을 제공할 수 있습니다.

다음 예시에서는 IN 술어를 사용하여 sample_mflix.movies 컬렉션에서 year 값이 1994 또는 1996 인 문서를 조회합니다.

var inResult = session.createQuery("from Movie where year in (:first, :second)", Movie.class) .setParameter("first", 1994) .setParameter("second", 1996) .getResultList();for (var m : inResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 IN 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "year": { "$in": [ 1994, 1996 ] } }}

빈 리스트는 유효하지만 어떤 문서와도 일치하지 않습니다. 예시들어, year in ()은(는) 어떤 문서와도 일치하지 않습니다.

참고

IN 연산자 제한 사항

Hibernate ORM 확장은 IN 왼쪽의 값이 필드 경로인 경우에만 IN 조건자를 지원합니다. Hibernate ORM 확장은 다음 IN 조건자를 지원하지 않습니다.

  • 서브쿼리를 값 목록으로 사용합니다.

  • :value in m.cast에서와 같이 배열 값 표현식에 대해 값을 테스트합니다. 배열 필드에 대해 값을 일치시키려면 대신 array_contains() 함수를 사용하세요.

배열 쿼리에 대해 자세히 알아보려면 이 가이드의 배열 필드 쿼리 섹션을 참조하세요.

NOT IN 조건자는 필드 값이 지정된 목록의 어떤 값과도 일치하지 않는 문서를 찾습니다. NOT IN은(는) IN 조건자와 동일한 목록 형식을 허용하며 동일한 제한 사항을 가집니다.

다음 예시 NOT IN 조건자를 사용하여 sample_mflix.movies 컬렉션에서 "Romeo and Juliet" 또는 "Best in Show" 이외의 title 값이 있는 문서를 조회합니다. NOT IN는 나열된 값만 제외하므로 예시에서는 setMaxResults() 메서드를 호출하여 결과 집합을 10개의 문서로 제한합니다.

var notInResult = session.createQuery("from Movie where title not in (:first, :second)", Movie.class) .setParameter("first", "Romeo and Juliet") .setParameter("second", "Best in Show") .setMaxResults(10) .getResultList();for (var m : notInResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 NOT IN 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "title": { "$nin": [ "Romeo and Juliet", "Best in Show" ] } }}

$nin은 빈 값 목록에 대해 모든 문서를 일치시키기 때문에, title not in ()은 모든 문서를 일치시킵니다.

참고

NOT IN 제한 사항

Hibernate ORM 확장은 NOT IN 왼쪽의 값이 필드 경로인 경우에만 NOT IN 조건자를 지원합니다. Hibernate ORM 확장은 다음 NOT IN 조건자를 지원하지 않습니다.

  • 서브쿼리를 값 목록으로 사용합니다.

  • 배열 값 표현식에 대해 값을 테스트합니다(예: :value not in m.cast).

참고

Null 의미 체계

행 값 술어는 Hibernate ORM의 3항 논리보다는 MongoDB 쿼리 언어의 null 의미 체계를 따릅니다. 따라서 NOT IN 술어는 구성 요소가 null이거나 누락된 문서를 찾습니다. 더 자세히 알아보려면 이 가이드의 필드 값을 Null과 비교 섹션을 참조하세요.

IS NULL 술어는 null 값이거나 값이 없는 특정 필드를 가진 문서를 일치시킵니다.

술어 대신 비교 연산자를 사용하여 필드를 null와 비교하려면 이 가이드의 필드 값을 Null과 비교 섹션을 참조하세요.

다음 예시 IS NULL 술어를 사용하여 sample_mflix.movies 컬렉션 에서 누락되었거나 null cast 값이 있는 문서를 조회 .

var isNullResult = session.createQuery("from Movie where cast is null", Movie.class) .getResultList();for (var m : isNullResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 IS NULL 유시자를 다음 $match 단계로 변환합니다. 이 단계는 필드가 명시적으로 null 이거나 없는 문서와 일치합니다.

{ "$match": { "cast": { "$eq": null } }}

IS NOT NULL 조건자는 null이 아니거나 누락되지 않은 값을 가진 필드가 있는 문서를 일치시킵니다.

다음 예시는 IS NOT NULL 술어를 사용하여 sample_mflix.movies 컬렉션에서 directors 값을 가진 문서를 조회합니다.

var isNotNullResult = session.createQuery("from Movie where directors is not null", Movie.class) .getResultList();for (var m : isNotNullResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 IS NOT NULL 조건을 다음 $match 단계로 번역합니다. 이 단계는 필드가 존재하고 명시적으로 null 아닌 문서와 일치합니다.

{ "$match": { "directors": { "$ne": null } }}

LIKE 위여 설정은 대소문자를 구분하며 필드 값이 지정된 패턴과 일치하는 문서를 찾습니다. 패턴은 필드의 전체 값과 일치됩니다. 그리고 다음 와일드카드 문자를 사용할 수 있습니다.

  • %: 0개 이상의 문자와 일치합니다.

  • _: 정확히 한 문자와 일치합니다.

접두사를 일치시키려면 패턴 끝에 %을(를) 포함하고, 접미사를 일치시키려면 패턴 시작 부분에 %을(를) 포함하세요.

팁

와일드카드 문자 이스케이프

% 또는 _을(를) 리터럴 문자로 일치시키려면 ESCAPE 조항을 사용합니다. 예시, title like '100!%' escape '!'은 "100%" 값과 일치합니다. ESCAPE을 %, _ 또는 에스케이프 문자 자체와 함께 사용할 수 있습니다. 다른 문자와 함께 사용하거나 패턴 끝에 남겨 두면 Hibernate ORM 확장이 IllegalArgumentException을 발생시킵니다.

다음 예시 LIKE 술어를 사용하여 sample_mflix.movies 컬렉션 에서 title 값이 "W" 로 시작하고 그 뒤에 단일 문자가 오고 "r" 가 오는 문서를 조회 .

var likeResult = session.createQuery("from Movie where title like 'W_r%'", Movie.class) .getResultList();for (var m : likeResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 LIKE 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "title": { "$regex": /^W.r.*$/s } }}

참고

LIKE 술어 제한 사항

LIKE와 비교하는 값은 '%War%'와 같은 string 리터럴이어야 합니다. Hibernate ORM 확장은 패턴에 대해 바인딩된 매개변수(like :pattern), 다른 필드(like m.plot) 또는 계산된 값(like concat('War', '%'))을 지원하지 않으며, 이를 사용하면 FeatureNotSupportedException를 throw합니다.

HQL LIKE 조건자에 대해 자세히 학습하려면 하이버네이트 ORM 문서의 하이버네이트 쿼리 언어 가이드 를 참조하세요.

NOT LIKE 술어는 필드 값이 지정된 패턴과 일치하지 않는 문서를 일치시킵니다. Hibernate ORM 확장은 LIKE 술어가 생성하는 $regex 필터를 부정하고 LIKE 술어와 동일한 패턴 일치 동작 및 제한 사항을 사용합니다.

다음 예시는 NOT LIKE 예측자를 사용하여 sample_mflix.movies 컬렉션에서 "The" (으)로 시작하지 않는 title 값이 있는 문서를 조회합니다. 술어가 대부분의 문서와 일치하므로 예시에서는 setMaxResults() 메서드를 호출하여 결과 집합을 5개의 문서로 제한합니다.

var notLikeResult = session.createQuery("from Movie where title not like 'The%'", Movie.class) .setMaxResults(5) .getResultList();for (var m : notLikeResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 NOT LIKE 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "$nor": [ { "title": { "$regex": /^The.*$/s } } ] }}

ILIKE 술어는 LIKE 술어의 대소문자를 구분하지 않는 형식입니다. Hibernate ORM 확장은 LIKE 술어가 생성하는 $regex 필터를 대소문자를 구분하지 않는 것으로 표시하고 LIKE 술어와 동일한 패턴 일치 동작 및 제한 사항을 사용합니다.

다음 예시에서는 ILIKE 술어를 사용하여 sample_mflix.movies 컬렉션에서 "Star"을(를) 포함하는 title 값을 가진 문서를 조회합니다.

var ilikeResult = session.createQuery("from Movie where title ilike '%Star%'", Movie.class) .getResultList();for (var m : ilikeResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 ILIKE 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "title": { "$regex": /^.*Star.*$/is } }}

NOT ILIKE 술어는 NOT LIKE 술어의 대소문자를 구분하지 않는 형식입니다. Hibernate ORM 확장은 ILIKE 술어가 생성하는 대소문자를 구분하지 않는 $regex 필터를 부정하며 LIKE 술어와 동일한 패턴 매칭 동작 및 제한 사항을 사용합니다.

다음 예시는 NOT ILIKE 술어를 사용하여 sample_mflix.movies 컬렉션에서 "The"을(를) 포함하지 않는 title 값을 가진 문서를 조회합니다. 술어가 대부분의 문서와 일치하므로 예시에서는 setMaxResults() 메서드를 호출하여 결과 집합을 5개의 문서로 제한합니다.

var notIlikeResult = session.createQuery("from Movie where title not ilike '%The%'", Movie.class) .setMaxResults(5) .getResultList();for (var m : notIlikeResult) { System.out.println("Title: " + m.getTitle());}

Hibernate ORM 확장은 이전 NOT ILIKE 조건자를 다음 $match 단계로 변환합니다.

{ "$match": { "$nor": [ { "title": { "$regex": /^.*The.*$/is } } ] }}

쿼리 문에서 다음 연산자를 사용하여 여러 쿼리 기준을 결합할 수 있습니다.

  • and: 모든 기준 일치

  • or: 모든 기준과 일치

  • not: 기준과 일치하지 않음

다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "The Godfather" 이고 year 값이 1972 인 문서 조회합니다.

var logicalResult = session.createQuery("from Movie where title = :t and year = :y", Movie.class) .setParameter("t", "The Godfather") .setParameter("y", 1972) .getSingleResult();System.out.println("Title: " + logicalResult.getTitle());

ObjectId 값을 기준으로 문서 조회 하려면 세션을 사용하는 경우 이 값을 get() 메서드에 인수로 전달하고, 엔터티 관리자를 사용하는 경우 find() 메서드에 전달할 수 있습니다. .

다음 예시 ObjectId 값으로 sample_mflix.movies 컬렉션 에서 문서 검색합니다.

var movieById = session.get(Movie.class, new ObjectId("573a13a8f29313caabd1d53c"));

@Struct 집계 임베더블을 생성하여 MongoDB 내장된 문서를 나타낼 수 있습니다. 그런 다음 Hibernate ORM 확장을 사용하여 특정 상위 엔터티와 연결된 @Struct 집계 임베더블을 가져올 수 있습니다.

팁

내장된 문서 표현에 대해 자세히 학습 엔터티 만들기 가이드 에서 내장된 데이터를 참조하세요.

다음 예시 sample_mflix.movies 컬렉션 에서 title 값이 "Hairspray" 인 문서를 검색합니다. 그런 다음 이 코드는 Awards @Struct 임베딩 가능 애그리게이션을 저장하는 awards 필드 가져와서 Awards 임베딩 가능 유형의 wins 필드 출력합니다.

var embeddedResult = session.createQuery("select awards from Movie where title = :title", Awards.class) .setParameter("title", "Hairspray") .getResultList();for (var a : embeddedResult) { System.out.println("Award wins: " + a.getWins());}

HQL 또는 JPQL 쿼리의 SELECT, WHERE, ORDER BY 및 UPDATE 절에서 점으로 구분된 경로 표현식을 사용하여 임베드 가능한 유형의 필드를 참조할 수 있습니다. 경로 표현식에서 여러 임베디드 이름을 연결하여 다른 임베디드 내의 중첩된 임베디드에 있는 필드를 참조할 수도 있습니다.

중요

쿼리 제한 사항

경로 표현식은 사용자 지정 읽기 표현식을 정의하기 위해 @ColumnTransformer 주석을 사용하는 임베더블 필드를 지원하지 않습니다.

Hibernate ORM 확장 기능은 엔티티 모델을 빌드할 때 다음 @Struct 집계 임베디드 매핑도 거부합니다.

  • @Id 필드로 사용되는 @Struct 애그리게이션 임베딩 가능

  • 다형성 @Struct 애그리게이션 임베딩 가능 계층 구조

이러한 유형의 필드를 참조하기 위해 경로 표현식을 사용할 수 없습니다.

다음 예시는 경로 표현식을 사용하여 sample_mflix.movies 컬렉션의 문서를 필터링합니다. sample_mflix.movies 컬렉션에는 "Hairspray" 영화가 두 편 있습니다. 한 "Hairspray" 영화는 1998에서 제작되었고, 다른 하나는 2007에서 제작되었습니다. 이 쿼리는 title 값이 "Hairspray" 이고 awards.wins 값이 10보다 큰 문서와 일치합니다.

var matchingDocument = session.createQuery("from Movie where title = :title and awards.wins > :minWins", Movie.class) .setParameter("title", "Hairspray") .setParameter("minWins", 10) .getResultList();for (var m : matchingDocument) { System.out.println("Title: " + m.getTitle() + ", Year: " + m.getYear());}

엔티티의 필드가 @Struct 집계 임베디드 배열을 저장하는 경우 EXISTS 하위 쿼리를 사용하여 해당 배열의 요소 중 하나 이상이 기준을 충족하는 상위 문서를 일치시킬 수 있습니다. Hibernate ORM 확장은 하위 쿼리를 MongoDB $elemMatch 연산자로 변환하며, 이 연산자는 모든 기준을 동일한 배열 요소에 적용합니다.

참고

이 섹션에서는 sample_restaurants 데이터베이스를 사용합니다

이 섹션의 예시에서는 이 가이드의 다른 곳에서 사용된 sample_mflix.movies 컬렉션 대신 sample_restaurants.restaurants 컬렉션을 사용합니다.

이 예시를 실행하려면 연결 문자열에서 sample_restaurants 데이터베이스에 연결하세요. sample_restaurants 데이터베이스에 대해 자세히 학습하려면 Atlas 샘플 데이터 세트 를 참조하세요.

다음 Restaurant 엔티티는 restaurants 컬렉션에 매핑되며 grades 필드에 Grade 임베디드 목록을 저장합니다.

package org.example; import com.mongodb.hibernate.annotations.ObjectIdGenerator;import jakarta.persistence.Column;import org.bson.types.ObjectId;import java.util.List; import jakarta.persistence.Entity;import jakarta.persistence.Id;import jakarta.persistence.Table; @Entity@Table(name = "restaurants")public class Restaurant { @Id @ObjectIdGenerator @Column(name = "_id") private ObjectId id; private String name; private String borough; private List<Grade> grades; public Restaurant(String name, String borough, List<Grade> grades) { this.name = name; this.borough = borough; this.grades = grades; } public Restaurant() { } public ObjectId getId() { return id; } public void setId(ObjectId id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getBorough() { return borough; } public void setBorough(String borough) { this.borough = borough; } public List<Grade> getGrades() { return grades; } public void setGrades(List<Grade> grades) { this.grades = grades; } }

다음 Grade @Struct 집계 포함 가능 객체는 grades 배열의 각 요소를 나타냅니다.

package org.example;import jakarta.persistence.*;import org.hibernate.annotations.Struct; @Embeddable@Struct(name = "Grade")public class Grade { private String grade; private int score; public Grade() { } public Grade(String grade, int score) { this.grade = grade; this.score = score; } public String getGrade() { return grade; } public void setGrade(String grade) { this.grade = grade; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } }

팁

임베더블 배열에 대해 자세히 알아보려면 엔터티 만들기 가이드의 임베디드 데이터를 참조하세요.

restaurants 컬렉션의 문서는 다음과 유사합니다.

{ "_id": { "$oid": "5eb3d668b31de5d588f4292a" }, "name": "Morris Park Bake Shop", "borough": "Bronx", "cuisine": "Bakery", "grades": [ { "date": { "$date": 1393804800000 }, "grade": "A", "score": 2 }, { "date": { "$date": 1299715200000 }, "grade": "B", "score": 14 } ]}

다음 예시는 grades 배열 요소 중 grade 값이 "B" 이고 score 값이 12인 레스토랑을 조회합니다. 두 조건이 동일한 하위 쿼리에 나타나므로 동일한 배열 요소와 일치해야 합니다.

var existsResult = session.createQuery( "from Restaurant r where exists (select g.grade from r.grades g where g.grade = :grade and g.score = :score)", Restaurant.class) .setParameter("grade", "B") .setParameter("score", 12) .getResultList();for (var r : existsResult) { System.out.println("Name: " + r.getName());}

Hibernate ORM 확장은 앞서 언급한 EXISTS 하위 쿼리를 다음 $match 단계로 변환합니다.

{ "$match": { "grades": { "$elemMatch": { "grade": { "$eq": "B" }, "score": { "$eq": 12 } } } }}

하이버네이트 ORM 확장은 배열 필드 쿼리를 위해 다음 함수를 지원합니다.

  • array_contains(): 배열 필드 에 지정된 값이 포함된 문서 일치

  • array_contains_nullable(): 배열 필드 null 값을 포함하여 지정된 값이 포함된 문서를 일치시킵니다.

  • array_includes(): 배열 필드 다른 배열 값이 포함된 문서 일치

  • array_includes_nullable(): 배열 필드 null 값을 포함한 다른 배열 값이 포함된 문서 일치

팁

배열 함수에 대해 자세히 학습하려면 하이버네이트 ORM 사용자 가이드에서 배열을 처리하기 위한 함수 를 참조하세요.

다음 예시 array_contains() 함수를 사용하여 sample_mflix.movies 컬렉션 의 cast 배열 필드 에 값이 "Kathryn Hahn" 인 문서를 조회 .

var arrayResult = session.createQuery("from Movie where array_contains(cast, :actor)", Movie.class) .setParameter("actor", "Kathryn Hahn") .getResultList();for (var m : arrayResult) { System.out.println("Title: " + m.getTitle());}

HQL 및 JPQL 쿼리에서 집계 함수를 사용하여 쿼리 결과를 그룹화 및 요약하거나 HAVING 절을 사용하여 그룹화된 결과를 필터링할 수 있습니다. HQL 및 JPQL은 다음 집계 함수를 지원합니다.

  • count()

  • sum()

  • avg()

  • min()

  • max()

참고

GROUP BY 요구 사항

집계 함수에는 GROUP BY 절이 필요합니다. 집계 함수를 사용하고 결과를 그룹화하지 않는 쿼리(select count(*) from Movie과 같은) 는 아직 지원되지 않습니다. SELECT 절에 있는 집계 필드 외 필드는 GROUP BY 절에도 포함되어야 합니다.

다음 예시는 1920 년에서 1924 년 사이에 개봉된 영화를 연도별로 그룹화합니다. 각 연도별로 영화 수와 모든 영화의 총 상영 시간을 반환합니다. HAVING 절에는 총 상영 시간이 300 분보다 긴 영화가 있는 연도만 포함되며, 결과는 연도별로 정렬됩니다.

var aggregateResult = session.createQuery( "select year, count(*), sum(runtime) from Movie where year between 1920 and 1924 " + "group by year having sum(runtime) > 300 order by year", Object[].class) .getResultList();for (var row : aggregateResult) { System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Total runtime: " + row[2]);}

필드의 고유 값만 요약하려면 집계 함수 내에 distinct 키워드를 포함하세요. distinct은(는) count(), sum(), avg(), min(), max() 집계 함수와 함께 사용할 수 있습니다.

count(distinct x) null 값을 무시하므로 x의 고유한 null이 아닌 값만 계산합니다. min() 및 max()의 경우 distinct 키워드는 결과에 영향을 주지 않습니다.

다음 예시는 1998 년에서 2000 년 사이에 개봉된 영화를 연도별로 그룹화합니다. 각 연도에 대해 영화 수와 고유 제목 수를 반환하고 연도별로 결과를 정렬합니다.

var distinctResult = session.createQuery( "select year, count(*), count(distinct title) from Movie where year between 1998 and 2000 " + "group by year order by year", Object[].class) .getResultList();for (var row : distinctResult) { System.out.println("Year: " + row[0] + ", Count: " + row[1] + ", Distinct titles: " + row[2]);}

MongoDB 데이터에서 다른 작업을 수행하는 방법에 대해 자세히 학습 CRUD 작업 수행 가이드 참조하세요.

연관으로 연결된 엔터티 간에서 쿼리하는 방법을 학습하려면, 컬렉션 간 엔터티 조인 가이드를 참조하세요.

datetime 값의 일부를 반환하거나 datetime 값을 string으로 렌더링하는 방법을 알아보려면 쿼리에서 Datetime 함수 사용 가이드를 참조하세요.

HQL 및 JPQL을 사용하여 쿼리를 실행 방법에 대해 자세히 학습하려면 하이버네이트 ORM 문서에서 하이버네이트 쿼리 언어 가이드 를 참조하세요.