개요
Mongoid의 연관 관계를 사용하면 모델 간의 관계를 생성할 수 있습니다. 이 가이드 에서는 포함된 연결을 사용하여 동일한 컬렉션 에 서로 다른 유형의 문서를 저장 방법을 학습 수 있습니다. Mongoid는 다음 매크로와의 포함된 연관 관계를 지원합니다:
embeds_oneembeds_manyembedded_inrecursively_embeds_onerecursively_embeds_many
다음 섹션에서는 이러한 연결 유형을 사용하는 방법을 설명합니다.
Embeds One
클래스 모델에 다른 클래스 유형의 내장된 문서 포함되도록 지정하려면 상위 클래스에서는 embeds_one 매크로를 사용하고 내장된 클래스에서는 embedded_in 매크로를 사용합니다. 다음 예시 Label 클래스가 포함된 Band 클래스를 만듭니다.
class Band include Mongoid::Document embeds_one :label end class Label include Mongoid::Document field :name, type: String embedded_in :band end
Mongoid는 embeds_one 매크로로 포함된 문서를 상위 문서 에 포함된 클래스와 이름이 같은 필드 로 저장합니다. 앞의 Label 문서는 다음 예시 와 같이 Band 문서 에 저장됩니다.
# Band document { "_id" : ObjectId("..."), "label" : { "_id" : ObjectId("..."), "name" : "Periphery", } }
다음 예시 와 같이 store_as 옵션을 사용하여 내장된 문서 다른 이름으로 저장 수 있습니다.
class Band include Mongoid::Document embeds_one :label, store_as: "record_label" end
Embeds Many
클래스 모델에 서로 다른 클래스 유형의 내장된 문서가 여러 개 포함되도록 지정하려면 상위 클래스에서는 embeds_many 매크로를 사용하고, 내장된 클래스에서는 embedded_in 매크로를 사용합니다. 다음 예시 여러 개의 Album 유형 문서가 포함된 Band 클래스를 만듭니다.
class Band include Mongoid::Document embeds_many :albums end class Album include Mongoid::Document field :name, type: String embedded_in :band end
Mongoid는 상위 문서 에 embeds_many 매크로로 포함된 문서를 포함된 클래스와 동일한 이름의 배열 필드 로 저장합니다. 앞의 Album 문서는 다음 예시 와 같이 Band 문서 에 저장됩니다.
{ "_id" : ObjectId("..."), "albums" : [ { "_id" : ObjectId("..."), "name" : "Omega", } ] }
다음 예시 와 같이 store_as 옵션을 사용하여 내장된 문서 다른 이름으로 저장 수 있습니다.
class Band include Mongoid::Document embeds_many :albums, store_as: "records" end
재귀적 임베딩
recursively_embeds_one 및 recursively_embeds_many 매크로를 사용하여 동일한 유형의 문서를 하나 이상 상위 클래스에 포함할 수 있습니다. 두 매크로 모두 parent_* 메서드와 child_* 메서드를 통해 상위 및 하위 문서에 대한 접근자를 제공하며, 여기서 * 는 클래스 이름을 나타냅니다. 다음 예시 여러 개의 다른 Band 문서를 재귀적으로 포함하여 여러 밴드 이름을 나타내는 Band 클래스를 만듭니다.
class Band include Mongoid::Document field :name, type: String recursively_embeds_many end
다음 예시 와 같이 parent_band 및 child_band 메서드를 통해 상위 및 하위 문서에 액세스 할 수 있습니다.
root = Band.new(name: "Linkin Park") # Add child bands child_one = root.child_band.build(name: "Lincoln Park") child_two = root.child_band.build(name: "Xero") # Access parent band child_one.parent_band # Outputs: root
임베디드 연관 관계 쿼리
점 표기법 사용하여 상위 클래스의 컬렉션 을 쿼리할 때 내장된 문서에 액세스 할 수 있습니다.
다음 예시 점 표기법 사용하여 Band 클래스에 포함된 Tour 유형 문서를 쿼리 . 이 쿼리 tours.year 값이 2000 이상인 문서를 반환합니다.
Band.where('tours.year' => {'$gte' => 2000})
다음 예시 와 같이 pluck 프로젝션 메서드를 사용하여 연결된 상위 문서를 검색하지 않고도 내장된 문서를 조회 할 수 있습니다.
# Get awards for bands that have toured since 2000 Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)
Mongoid 쿼리 메서드를 사용하여 애플리케이션 에 이미 로드된 문서의 포함된 연관 관계를 쿼리 할 수 있는 임베디드 매칭을 수행할 수 있습니다. Mongoid는 서버 에 쿼리를 보내지 않고 임베디드 매칭을 구현합니다.
포함된 일치 항목이 지원되는 쿼리 연산자는 다음과 같습니다.
다음 예시 $gte 비교 연산자 를 사용하여 로드된 Band 문서 의 포함된 tours 필드 쿼리합니다.
band = Band.where(name: 'Astral Projection').first tours = band.tours.where(year: {'$gte' => 2000})
로드된 문서에 포함된 매칭에는 다음과 같은 알려진 제한 사항이 있습니다.
다음 기능에 대해서는 임베디드 매칭이 구현되지 않습니다.
$where와같은 JavaScript 코드를 실행하는 연산자
$expr 및 $jsonSchema와같은 다른 서버 기능을 통해 구현되는 연산자
Mongoid는
Range인수를$gte및$lte조건이 있는 해시로 확장합니다. 이로 인해 경우에 따라 잘못된 쿼리가 발생할 수 있으며InvalidQuery예외가 발생합니다.$regex연산자 사용하면$options필드 에 옵션을 제공하면서 정규 표현식 객체 패턴 으로 지정할 수 없습니다. 정규 표현식 패턴 이 문자열인 경우에만 옵션을 제공할 수 있습니다.
_id 필드 생략
기본값 으로 Mongoid는 내장된 문서에 _id 필드 추가합니다. 모델에서 _id 필드 명시적으로 지정하고 기본값 을 생략하여 내장된 문서에서 이 필드 생략할 수 있습니다. 다음 예시 _id 필드 Albums 클래스에 추가하지 않도록 Mongoid에 지시합니다.
class Album include Mongoid::Document field :name, type: String field :_id, type: Object embedded_in :band end
앞의 Albums 클래스에서는 _id 필드 자동으로 추가되지 않습니다. 기본값 이 없으면 모델에 값을 제공하지 않는 한 Mongoid가 데이터베이스 에 값을 저장 하지 않습니다.
포함된 연관 관계 삭제
다음 방법 중 하나를 사용하여 embeds_many 연관 관계에서 하위 문서를 삭제 수 있습니다.
cleardelete_alldestroy_all
clear 메서드는 $unset 연산자 연산자 사용하여 상위 문서 에서 내장된 연결 전체를 제거 . clear 메서드는 destroy 콜백을 실행 하지 않습니다. 다음 예시 clear 메서드를 사용하여 Band 클래스에서 포함된 연결을 모두 제거 .
band = Band.find(...) band.tours.clear
delete_all 메서드는 $pullAll 연산자 연산자 사용하여 포함된 연관 관계에서 문서를 제거 . delete_all 는 아직 로드되지 않은 경우 연관 관계를 로드한 다음 애플리케이션 에 존재하는 문서만 제거합니다. delete_all 메서드는 destroy 콜백을 실행 하지 않습니다. 다음 예시 delete_all 메서드를 사용하여 Band 클래스에서 내장된 Album 문서를 모두 제거 .
band = Band.find(...) band.tours.delete_all
destroy_all 또한 메서드는 $pullAll 연산자 연산자 사용하여 포함된 연결에서 문서를 제거 . 또한 관련 문서에 정의된 destroy 콜백을 실행합니다. 다음 예시 destroy_all 메서드를 사용하여 Band 클래스에서 내장된 Album 문서를 모두 제거 .
band = Band.find(...) band.tours.destroy_all