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

포함된 관계 및 수동 참조

이 가이드에서 MongoDB Entity 프레임워크 Core 제공자을 사용하여 MongoDB 데이터베이스의 문서 간의 관계를 모델링하는 방법을 학습할 수 있습니다. EF Core Provider는 다음 관계 유형을 지원합니다.

  • 포함된 관계: 상위 문서 내에 직접 포함된 하위 문서입니다. 이는 MongoDB 의 일대일 및 일대다 관계에 권장되는 접근 방식입니다.

  • 수동 참조: 문서를 서브 문서로 임베딩하는 대신 필드에 ID를 저장하여 다른 문서를 참조하는 문서입니다. 이 방법은 다대다 관계를 모델링하는 데 유용합니다. 또는 문서에 대해 독립적으로 액세스해야 할 때 유용합니다.

쿼리 패턴에 맞게 스키마 디자인

MongoDB용 데이터를 모델링할 때 먼저 애플리케이션이 가장 자주 실행하는 작업을 결정합니다. 그리고 해당 작업을 효율적으로 지원하는 문서 구조를 선택합니다. MongoDB에서 가장 효율적인 스키마는 관계형 데이터를 위해 사용하는 스키마와 일치하지 않을 수 있습니다. 대신 자주 함께 조회되는 데이터, 자주 변경되는 값, 시간이 지남에 따라 변경되는 데이터 관계를 고려합니다.

데이터 모델링 및 관계형 데이터베이스에서 MongoDB Server로 마이그레이션하는 방법에 대해 자세히 학습하려면 MongoDB Server 문서에서 SQL - MongoDB 매핑 차트MongoDB의 데이터 모델링 을 참조하세요.

부모 문서에 내장된 문서를 내장하려면 소유 개체로 내장된 문서의 모델을 지정합니다. 내장된 관계는 관계를 모델링하는 MongoDB 네이티브 방식이며, 자주 함께 액세스하는 문서에 대해 더 나은 성능을 제공합니다.

관련 데이터가 일반적으로 상위 데이터의 컨텍스트에서 표시되고 내장된 데이터의 크기가 합리적으로 제한되는 경우 내장된 문서를 사용합니다. 여기에는 주소, 설정 또는 제한된 최근 항목 목록과 같은 작은 하위 값 집합이 포함됩니다. 문서를 임베드할 때 MongoDB Server 단일 데이터베이스 작업으로 관련 데이터를 검색하고 단일 문서 내에서 관련 데이터를 원자적으로 업데이트하여 성능을 향상시킬 수 있습니다.

다음 경우에 데이터 임베딩을 고려해 보세요.

  • 애플리케이션은 일반적으로 부모 및 자식 데이터를 함께 읽습니다. 별도 호출하는 것보다 하나의 쿼리에서 모든 것을 가져오는 것이 더 효율적입니다.

  • 관련 데이터는 명확한 상한 없이 증가하지 않습니다. 버든디드 데이터로 인해 문서가 무기한적으로 증가하거나 MongoDB의 16MB 문서 크기 제한에 도달하지 않습니다.

  • 관련 데이터는 부모와 독립적으로 자주 변경되지 않습니다. 이로 인해 부모 문서를 다시 작성하는 데 소요되는 오버헤드가 줄어듭니다.

참고

중찹 계층 구조

중척된 소유 개체의 속성을 업데이트하면 EF Core 제공자가 전체 루트 문서를 다시 작성합니다. 중척 수준이 3개 이상인 개체 계층의 경우 이 쓰기 비용이 증가합니다. 이는 트리의 깊은 곳의 작은 변경이 전체 부모 문서를 다시 작성하도록 트리거하기 때문입니다. 디프 중척을 사용하고 애플리케이션이 자주 쓰기 작업을 수행하는 경우 계층을 평면화하거나 내부 소유 개체를 수동 참조로 대체하는 것을 고려해야 합니다.

자세한 내용은 MongoDB Server 문서의 내장 데이터 를 참조하세요.

소유한 엔티티는 다음과 같은 방법으로 지정할 수 있습니다.

  • [소유] 속성: 서브문서의 모델 클래스에 [Owned] 데이터 주석 속성을 적용합니다. 이 방식은 선언적이고 간결하지만, 소유한 유형의 모든 사용에 전역적으로 적용되므로 유연성이 떠어집니다.

  • Fluent API: DbContext 구성에서 OwnsOne() 또는 OwnsMany() 메서드를 호출합니다. 이 방법은 모델 클래스를 수정하지 않고도 특정 개체에 대해 관계를 다르게 구성할 수 있어 더 많은 제어와 유연성을 제공합니다.

다음 섹션에서는 단일 및 다중 소유 개체 모델링에 대한 이러한 접근 방법의 예시를 제공합니다.

부모 문서 내에 단일 문서를 포함하려면 DbContext 구성에서 OwnsOne() 메서드를 호출하거나 포함된 클래스에 [Owned] 특성을 적용합니다.

다음 예시는 내장된 Address 문서를 포함하는 Customer 개체를 보여줍니다. [Owned] Attribute 또는 Fluent API 탭을 선택하여 해당 구문을 확인하세요.

[Owned]
public class Address
{
public string Street { get; set; } = null!;
public string City { get; set; } = null!;
public string Country { get; set; } = null!;
}
public class Customer
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public Address Address { get; set; } = null!;
}
public class CustomerDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; } = null!;
public CustomerDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>(c =>
{
c.OwnsOne(c => c.Address);
c.ToCollection("customers");
});
}
}

Customer 엔티티를 저장하면 MongoDB는 AddressCustomer 문서 내의 내장된 문서로 저장합니다. 다음 JSON에는 MongoDB에서 이 관계가 어떻게 표시되는지 나타냅니다.

{
"_id": ObjectId("..."),
"Name": "John Doe",
"Address": {
"Street": "123 Main St",
"City": "New York",
"Country": "USA"
}
}

다중 문서를 부모 문서에 포함하려면 OwnsMany() 메서드를 호출하거나 포함된 클래스에 [Owned] 속성을 적용하고 컬렉션 속성을 정의합니다.

다음 예시에는 여러 개의 중청된 Order 문서가 포함된 Customer 개체가 표시됩니다. [Owned] Attribute 또는 Fluent API 탭을 선택하여 해당 구문을 확인하세요.

[Owned]
public class Order
{
public string Product { get; set; } = null!;
public int Quantity { get; set; }
}
public class CustomerWithOrders
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public List<Order> Orders { get; set; } = new();
}
public class OrderDbContext : DbContext
{
public DbSet<CustomerWithOrders> Customers { get; set; } = null!;
public OrderDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CustomerWithOrders>(c =>
{
c.OwnsMany(c => c.Orders);
c.ToCollection("customers");
});
}
}

CustomerWithOrders 엔터티를 저장하면 MongoDB 다음 JSON 과 같이 Orders 를 내장된 문서의 배열 로 저장합니다.

{
"_id": ObjectId("..."),
"Name": "Jane Smith",
"Orders": [
{ "Product": "Laptop", "Quantity": 1 },
{ "Product": "Mouse", "Quantity": 2 }
]
}

내장되지 않은 개체 간의 관계를 모델링하려면 하나의 문서 ID를 다른 문서의 필드에 저장하여 수동으로 참조할 수 있습니다. 이 방식을 사용하려면 애플리케이션 코드에서 관계를 관리해야 합니다.

자식 세트가 매우 커질 수 있거나 관련 데이터가 자주 변경되는 경우 또는 부모와 독립적으로 관련 데이터를 정기적으로 쿼리하는 경우 참조를 사용합니다.

다음 경우 참조를 사용하는 것을 고려해 보세요.

  • 관련 데이터는 명확한 상한 없이 증가합니다. 제한이 없는 배열은 성능 문제를 일으키고 MongoDB의 16MB 문서 크기 제한에 도달할 수 있습니다.

  • 관련 엔터티를 자체적으로 쿼리해야 합니다. 부모 문서를 스캔하지 않고 하위 컬렉션을 직접 쿼리하고 인덱싱할 수 있습니다.

  • 관련 데이터는 부모와 독립적으로 자주 변경됩니다. 내장된 데이터의 자주 업데이트는 매번 전체 부모 문서를 다시 작성해야 하므로 비효율적입니다.

  • 애플리케이션은 일반적으로 부모 및 자식 데이터를 함께 읽지 않습니다. 참조를 사용하면 필요하지 않은 자식 데이터를 가져오는 것을 피할 수 있습니다.

  • 관계는 다대다 관계이거나 다른 복잡한 관계입니다.

  • 데이터를 복제하면 업데이트 오버헤드가 너무 많이 생긵니다.

자세히 학습하려면 MongoDB Server 문서의 참조 데이터 를 참조하세요.

다음 예시는 관련 개체에 대한 참조를 저장하는 방법을 보여줍니다.

public class Author
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
}
public class Book
{
public ObjectId Id { get; set; }
public string Title { get; set; } = null!;
// Store reference to Author by storing the Author's Id
public ObjectId AuthorId { get; set; }
}

관련 개체를 조회하려면 다음 예시에 표시된 것처럼 참조된 컬렉션을 별도로 쿼리해야 합니다.

// Query a book and its author
var book = db.Books.FirstOrDefault(b => b.Title == "My Book");
var author = db.Authors.FirstOrDefault(a => a.Id == book!.AuthorId);

부모 문서에 큰 배열이 포함되어 있지만 애플리케이션이 일반적으로 최근 또는 자주 액세스되는 항목만 사용하는 경우 하위 집합 패턴을 고려합니다.

하위 집합 패턴에서는 주 문서에 가장 자주 액세스되는 항목을 유지하고 나머지는 별도 컬렉션으로 이동합니다. 이 방법은 문서 크기를 줄이고 작업 세트의 대부분을 RAM에 유지하여 쿼리 성능을 향상시킬 수 있습니다.

이 패턴 임베딩의 성능 이점을 원하지만 전체 임베딩된 기록으로 인해 문서가 너무 커지거나 로드하기에 비용이 너무 많이 드는 경우에 유용합니다.

MongoDB의 스키마 설계에 대한 권장 사항에 대해 자세히 알아보려면 MongoDB Server 문서의 MongoDB의 데이터 모델링을 위한 권장 사항스키마 설계 를 참조하십시오.

MongoDB 에서의 데이터 모델링에 대해 자세히 학습하려면 MongoDB Server 문서에서 데이터 모델링 을 참조하세요.

Entity Framework Core의 소유 엔티티 유형에 대한 자세한 내용은 Microsoft Entity Framework Core 문서의 소유 엔티티 유형 을 참조하세요.

이 가이드에서 사용되는 메서드 또는 유형에 대해 자세히 알아보려면 다음 Microsoft API 문서를 참조하세요.