Docs Menu

집계

이 가이드에서는 MongoDB 코틀린(Kotlin) 드라이버에서 애그리게이션 작업 을 사용하는 방법을 배울 수 있습니다.

애그리게이션 작업은 MongoDB collection의 데이터를 처리하고 계산된 결과를 반환합니다. 쿼리 API의 일부인 MongoDB의 집계 파이프라인은 데이터 처리 파이프라인 개념을 모델로 합니다. 문서는 문서를 애그리게이션된 결과로 변환하는 다단계 파이프라인에 들어갑니다.

애그리게이션을 생각하는 또 다른 방식은 자동차 공장과 같습니다. 자동차 공장 내에는 조립 라인이 있으며, 여기에는 드릴과 용접기 등 특정 작업을 수행할 수 있는 특수 공구를 갖춘 조립 스테이션이 있습니다. 원부품이 공장에 들어오고, 공장은 변형되어 완제품으로 조립됩니다.

집계 파이프라인은 조립 라인이고, 집계 단계는 조립 스테이션이며, 작업 연산자는 특수 도구입니다.

find 작업을 사용하면 다음을 수행할 수 있습니다.

  • 반환할 문서 선택

  • 반환할 필드 선택

  • 결과 정렬

aggregation 작업을 사용하면 다음을 수행할 수 있습니다.

  • 모든 find 작업 수행

  • 필드 이름 바꾸기

  • 필드 계산

  • 데이터 요약

  • 그룹 값

집계 작업에는 몇 가지 가지 제한 사항이 있으므로 유의해야 합니다.

  • 반환된 문서는 BSON 문서 크기 제한인 16메가바이트를 초과하지 않아야 합니다.

  • 파이프라인 단계의 메모리 제한은 기본값 으로 100 메가바이트입니다. 필요한 경우 allowDiskUse 메서드를 사용하여 이 제한을 초과할 수 있습니다.

    중요

    $graphLookup 예외

    $graphLookup 단계는 100MB의 엄격한 메모리 제한을 가지며 allowDiskUse를 무시합니다.

이 예제에서는 MongoDB의 다음 데이터 컬렉션을 사용합니다.

[
{"name": "Sun Bakery Trattoria", "contact": {"phone": "386-555-0189", "email": "SunBakeryTrattoria@example.org", "location": [-74.0056649, 40.7452371]}, "stars": 4, "categories": ["Pizza", "Pasta", "Italian", "Coffee", "Sandwiches"]},
{"name": "Blue Bagels Grill", "contact": {"phone": "786-555-0102", "email": "BlueBagelsGrill@example.com", "location": [-73.92506, 40.8275556]}, "stars": 3, "categories": ["Bagels", "Cookies", "Sandwiches"]},
{"name": "XYZ Bagels Restaurant", "contact": {"phone": "435-555-0190", "email": "XYZBagelsRestaurant@example.net", "location": [-74.0707363, 40.59321569999999]}, "stars": 4, "categories": ["Bagels", "Sandwiches", "Coffee"]},
{"name": "Hot Bakery Cafe", "contact": {"phone": "264-555-0171", "email": "HotBakeryCafe@example.net", "location": [-73.96485799999999, 40.761899]}, "stars": 4, "categories": ["Bakery", "Cafe", "Coffee", "Dessert"]},
{"name": "Green Feast Pizzeria", "contact": {"phone": "840-555-0102", "email": "GreenFeastPizzeria@example.com", "location": [-74.1220973, 40.6129407]}, "stars": 2, "categories": ["Pizza", "Italian"]},
{"name": "ZZZ Pasta Buffet", "contact": {"phone": "769-555-0152", "email": "ZZZPastaBuffet@example.com", "location": [-73.9446421, 40.7253944]}, "stars": 0, "categories": ["Pasta", "Italian", "Buffet", "Cafeteria"]},
{"name": "XYZ Coffee Bar", "contact": {"phone": "644-555-0193", "email": "XYZCoffeeBar@example.net", "location": [-74.0166091, 40.6284767]}, "stars": 5, "categories": ["Coffee", "Cafe", "Bakery", "Chocolates"]},
{"name": "456 Steak Restaurant", "contact": {"phone": "990-555-0165", "email": "456SteakRestaurant@example.com", "location": [-73.9365108, 40.8497077]}, "stars": 0, "categories": ["Steak", "Seafood"]},
{"name": "456 Cookies Shop", "contact": {"phone": "604-555-0149", "email": "456CookiesShop@example.org", "location": [-73.8850023, 40.7494272]}, "stars": 4, "categories": ["Bakery", "Cookies", "Cake", "Coffee"]},
{"name": "XYZ Steak Buffet", "contact": {"phone": "229-555-0197", "email": "XYZSteakBuffet@example.org", "location": [-73.9799932, 40.7660886]}, "stars": 3, "categories": ["Steak", "Salad", "Chinese"]}
]

컬렉션의 데이터는 다음 Restaurant 데이터 클래스에 의해 모델링됩니다.

data class Restaurant(
val name: String,
val contact: Contact,
val stars: Int,
val categories: List<String>
) {
data class Contact(
val phone: String,
val email: String,
val location: List<Double>
)
}

집계를 수행하려면 집계 단계 목록을 MongoCollection.aggregate() 메서드에 전달합니다.

Kotlin 드라이버는 다음을 제공합니다. 애그리게이션 단계에 대한 빌더가 포함된 헬퍼 클래스입니다.

다음 예시에서 집계 파이프라인은 다음과 같습니다.

  • $match 단계를 사용하여 categories 배열 필드에 요소 Bakery(이)가 포함된 문서를 필터링합니다. 이 예시에서는 Aggregates.match(을)를 사용하여 $match 단계를 빌드합니다.

  • $group 단계를 사용하여 stars 필드를 기준으로 일치하는 문서를 그룹화하여 stars의 각 고유 값에 해당하는 문서 수를 누적합니다.

다음도 참조하세요.

집계 빌더를 사용하여 이 예시에 사용된 표현식을 작성할 수 있습니다.

data class Results(@BsonId val id: Int, val count: Int)
val resultsFlow = collection.aggregate<Results>(
listOf(
Aggregates.match(Filters.eq(Restaurant::categories.name, "Bakery")),
Aggregates.group("\$${Restaurant::stars.name}",
Accumulators.sum("count", 1))
)
)
resultsFlow.collect { println(it) }
Results(id=4, count=2)
Results(id=5, count=1)

이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.

MongoDB가 작업을 실행하는 방법에 대한 정보를 보려면 AggregateFlow 클래스의 explain() 메서드를 사용합니다. explain() 메서드는 실행 계획 및 성능 통계를 반환합니다. 실행 계획은 MongoDB가 작업을 완료할 수 있는 잠재적인 방법입니다. explain() 메서드는 성공적인 계획(MongoDB가 실행한 계획)과 거부된 계획을 모두 제공합니다.

explain() 메소드에 상세 수준을 전달하여 설명의 세부 정보 수준을 지정할 수 있습니다.

다음 표에는 설명 및 해당 사용 사례에 대한 모든 상세 수준이 나와 있습니다.

상세도 수준
사용 사례

ALL_PLANS_EXECUTIONS

쿼리를 실행하기 위해 MongoDB가 어떤 계획을 선택할지 알고 싶습니다.

EXECUTION_STATS

쿼리가 잘 수행되고 있는지 알고 싶습니다.

QUERY_PLANNER

쿼리에 문제가 있으며 문제를 진단하기 위해 가능한 한 많은 정보를 원합니다.

다음 예제에서는 실행 계획을 생성하는 애그리게이션 단계에 대한 성공적인 계획의 JSON 표현을 인쇄합니다.

data class Results (val name: String, val count: Int)
val explanation = collection.aggregate<Results>(
listOf(
Aggregates.match(Filters.eq(Restaurant::categories.name, "bakery")),
Aggregates.group("\$${Restaurant::stars.name}", Accumulators.sum("count", 1))
)
).explain(ExplainVerbosity.EXECUTION_STATS)
// Prettyprint the output
println(explanation.toJson(JsonWriterSettings.builder().indent(true).build()))
{
"explainVersion": "2",
"queryPlanner": {
// ...
},
"command": {
// ...
},
// ...
}

이 섹션에 언급된 주제에 대한 자세한 내용은 다음 리소스를 참조하세요.

코틀린(Kotlin) 드라이버는 $group과 함께 사용할 축적자 표현식용 빌더를 제공합니다. 다른 모든 표현식은 JSON 형식 또는 호환되는 문서 형식으로 선언해야 합니다.

다음 예시 중 하나의 구문은 $arrayElemAt 표현식을 정의합니다.

'카테고리' 앞의 $ 는 입력 문서의 '카테고리' 필드를 사용하여 이것이 필드 경로 임을 MongoDB에 알립니다.

Document("\$arrayElemAt", listOf("\$categories", 0))
// is equivalent to
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")

다음 예시에서 집계 파이프라인은 $project 단계와 다양한 Projections를 사용하여 name 필드와 categories 필드의 첫 번째 요소가 값인 계산된 필드 firstCategory를 반환합니다.

data class Results(val name: String, val firstCategory: String)
val resultsFlow = collection.aggregate<Results>(
listOf(
Aggregates.project(
Projections.fields(
Projections.excludeId(),
Projections.include("name"),
Projections.computed(
"firstCategory",
Document("\$arrayElemAt", listOf("\$categories", 0))
)
)
)
)
)
resultsFlow.collect { println(it) }
Results(name=Sun Bakery Trattoria, firstCategory=Pizza)
Results(name=Blue Bagels Grill, firstCategory=Bagels)
Results(name=XYZ Bagels Restaurant, firstCategory=Bagels)
Results(name=Hot Bakery Cafe, firstCategory=Bakery)
Results(name=Green Feast Pizzeria, firstCategory=Pizza)
Results(name=ZZZ Pasta Buffet, firstCategory=Pasta)
Results(name=XYZ Coffee Bar, firstCategory=Coffee)
Results(name=456 Steak Restaurant, firstCategory=Steak)
Results(name=456 Cookies Shop, firstCategory=Bakery)
Results(name=XYZ Steak Buffet, firstCategory=Steak)

이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.