집계
개요
이 가이드에서는 Java 드라이버를 사용하여 집계 작업을 수행하는 방법을 배울 수 있습니다.
집계 작업은 MongoDB 컬렉션 데이터를 처리하고 계산된 결과를 반환합니다. Query API의 일부인 MongoDB 집계 프레임워크는 데이터 처리 파이프라인 개념을 모델로 합니다. 문서는 하나 이상의 단계로 구성된 파이프라인에 들어가고, 이 파이프라인은 문서를 집계된 결과로 변환합니다.
집계 작업은 자동차 공장과 유사합니다. 자동차 공장에는 조립 라인이 있으며, 여기에는 드릴과 용접기 등 특정 작업을 수행할 수 있는 특수 공구를 갖춘 조립 스테이션이 있습니다. 원부품이 공장에 들어오면 조립 라인에서 이를 변형하고 조립하여 완제품으로 만듭니다.
집계 파이프라인은 조립 라인이고, 집계 단계는 조립 스테이션이며, 작업 연산자는 특수 도구입니다.
집계 및 찾기 연산 비교
찾기 조치를 사용하여 다음 조치을 수행할 수 있습니다:
반환할 문서 선택
반환할 필드 선택
결과 정렬
집계 조치를 사용하여 다음 조치를 수행할 수 있습니다:
찾기 작업 수행
필드 이름 바꾸기
필드 계산
데이터 요약
그룹 값
집계 작업에는 몇 가지 제한 사항을 염두에 두어야 합니다.
반환된 문서는 BSON 문서 크기 제한인 16메가바이트를 초과하지 않아야 합니다.
파이프라인 단계의 메모리 제한은 기본적으로 100MB입니다. 필요한 경우 allowDiskUse 메서드를 사용하여 이 제한을 초과할 수 있습니다.
유용한 참고 자료
실행 가능한 예시
클래스 가져오기
AggTour.java
라는 새 Java 파일을 만들고 다음 가져오기 성명서를 포함합니다.
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.ExplainVerbosity; import com.mongodb.client.model.Accumulators; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; import org.bson.Document; import org.bson.json.JsonWriterSettings; import java.util.Arrays; import java.util.List;
MongoDB 배포에 연결하기
public class AggTour { public static void main(String[] args) { // Replace the uri string with your MongoDB deployment's connection string String uri = "<connection string>"; MongoClient mongoClient = MongoClients.create(uri); MongoDatabase database = mongoClient.getDatabase("aggregation"); MongoCollection<Document> collection = database.getCollection("restaurants"); // Paste the aggregation code here } }
팁
MongoDB에 연결하는 방법에 대한 자세한 내용은 연결 가이드를 참조하세요.
샘플 데이터 삽입
collection.insertMany(Arrays.asList( new Document("name", "Sun Bakery Trattoria").append("contact", new Document().append("phone", "386-555-0189").append("email", "SunBakeryTrattoria@example.org").append("location", Arrays.asList(-74.0056649, 40.7452371))).append("stars", 4).append("categories", Arrays.asList("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")), new Document("name", "Blue Bagels Grill").append("contact", new Document().append("phone", "786-555-0102").append("email", "BlueBagelsGrill@example.com").append("location", Arrays.asList(-73.92506, 40.8275556))).append("stars", 3).append("categories", Arrays.asList("Bagels", "Cookies", "Sandwiches")), new Document("name", "XYZ Bagels Restaurant").append("contact", new Document().append("phone", "435-555-0190").append("email", "XYZBagelsRestaurant@example.net").append("location", Arrays.asList(-74.0707363, 40.59321569999999))).append("stars", 4).append("categories", Arrays.asList("Bagels", "Sandwiches", "Coffee")), new Document("name", "Hot Bakery Cafe").append("contact", new Document().append("phone", "264-555-0171").append("email", "HotBakeryCafe@example.net").append("location", Arrays.asList(-73.96485799999999, 40.761899))).append("stars", 4).append("categories", Arrays.asList("Bakery", "Cafe", "Coffee", "Dessert")), new Document("name", "Green Feast Pizzeria").append("contact", new Document().append("phone", "840-555-0102").append("email", "GreenFeastPizzeria@example.com").append("location", Arrays.asList(-74.1220973, 40.6129407))).append("stars", 2).append("categories", Arrays.asList("Pizza", "Italian")), new Document("name", "ZZZ Pasta Buffet").append("contact", new Document().append("phone", "769-555-0152").append("email", "ZZZPastaBuffet@example.com").append("location", Arrays.asList(-73.9446421, 40.7253944))).append("stars", 0).append("categories", Arrays.asList("Pasta", "Italian", "Buffet", "Cafeteria")), new Document("name", "XYZ Coffee Bar").append("contact", new Document().append("phone", "644-555-0193").append("email", "XYZCoffeeBar@example.net").append("location", Arrays.asList(-74.0166091, 40.6284767))).append("stars", 5).append("categories", Arrays.asList("Coffee", "Cafe", "Bakery", "Chocolates")), new Document("name", "456 Steak Restaurant").append("contact", new Document().append("phone", "990-555-0165").append("email", "456SteakRestaurant@example.com").append("location", Arrays.asList(-73.9365108, 40.8497077))).append("stars", 0).append("categories", Arrays.asList("Steak", "Seafood")), new Document("name", "456 Cookies Shop").append("contact", new Document().append("phone", "604-555-0149").append("email", "456CookiesShop@example.org").append("location", Arrays.asList(-73.8850023, 40.7494272))).append("stars", 4).append("categories", Arrays.asList("Bakery", "Cookies", "Cake", "Coffee")), new Document("name", "XYZ Steak Buffet").append("contact", new Document().append("phone", "229-555-0197").append("email", "XYZSteakBuffet@example.org").append("location", Arrays.asList(-73.9799932, 40.7660886))).append("stars", 3).append("categories", Arrays.asList("Steak", "Salad", "Chinese")) ));
기본 집계 예시
집계를 수행하려면 집계 단계 목록을 MongoCollection.aggregate()
메서드에 전달합니다.
Java 드라이버는 집계 단계에 대한 빌더가 포함된 Aggregates 헬퍼 클래스를 제공합니다.
다음 예시에서 집계 파이프라인은 다음과 같습니다.
$match 단계를 사용하여
categories
배열 필드에 요소Bakery
(이)가 포함된 문서를 필터링합니다. 이 예시에서는Aggregates.match
(을)를 사용하여$match
단계를 빌드합니다.$group 단계를 사용하여
stars
필드를 기준으로 일치하는 문서를 그룹화하여stars
의 각 고유 값에 해당하는 문서 수를 누적합니다.
참고
집계 빌더를 사용하여 이 예시에 사용된 표현식을 작성할 수 있습니다.
collection.aggregate( Arrays.asList( Aggregates.match(Filters.eq("categories", "Bakery")), Aggregates.group("$stars", Accumulators.sum("count", 1)) ) // Prints the result of the aggregation operation as JSON ).forEach(doc -> System.out.println(doc.toJson()));
앞의 집계는 다음과 같은 결과를 생성해야 합니다.
{"_id": 4, "count": 2} {"_id": 5, "count": 1}
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.
집계 설명 예시
MongoDB가 작업을 실행하는 방법에 대한 정보를 보려면 AggregateIterable
클래스의 explain()
메서드를 사용하세요. explain()
메서드는 실행 계획 및 성능 통계를 반환합니다. 실행 계획은 MongoDB가 작업을 완료할 수 있는 잠재적인 방법입니다. explain()
메서드는 MongoDB가 실행한 계획인 우선 계획과 거부된 계획을 모두 제공합니다.
팁
쿼리 계획 및 실행 통계에 대해 자세히 알아보려면 서버 매뉴얼의 결과 설명을 참조하세요.
explain()
메소드에 상세 수준을 전달하여 설명의 세부 정보 수준을 지정할 수 있습니다.
다음 표에는 설명 및 해당 사용 사례에 대한 모든 상세 수준이 나와 있습니다.
상세도 수준 | 사용 사례 |
---|---|
ALL_PLANS_EXECUTIONS | 쿼리를 실행하기 위해 MongoDB가 어떤 계획을 선택할지 알고 싶습니다. |
EXECUTION_STATS | 쿼리가 잘 수행되고 있는지 알고 싶습니다. |
QUERY_PLANNER | 쿼리에 문제가 있으며 문제를 진단하기 위해 가능한 한 많은 정보를 원합니다. |
다음 예시에서는 실행 계획을 생성하는 모든 집계 단계에 대한 성공 계획의 JSON 표현을 출력합니다.
Document explanation = collection.aggregate( Arrays.asList( Aggregates.match(Filters.eq("categories", "Bakery")), Aggregates.group("$stars", Accumulators.sum("count", 1)) ) ).explain(ExplainVerbosity.EXECUTION_STATS); String winningPlans = explanation .getEmbedded( Arrays.asList("queryPlanner", "winningPlan", "queryPlan"), Document.class ) .toJson(JsonWriterSettings.builder().indent(true).build()); System.out.println(winningPlans);
$group
단계가 실행 계획을 생성하는 유일한 단계이므로 이 예시에서는 다음 출력을 생성합니다.
{ "stage": "GROUP", "planNodeId": 2, "inputStage": { "stage": "COLLSCAN", "planNodeId": 1, "filter": { "categories": { "$eq": "Bakery" } }, "direction": "forward" } }
이 섹션에 언급된 주제에 대한 자세한 내용은 다음 리소스를 참조하세요.
출력 설명 서버 수동 입력
쿼리 플랜 서버 수동 입력
ExplainVerbosity API 문서
explain() API 문서
AggregateIterable API 문서
집계 표현식 예시
Java 드라이버는 $group
에 사용할 축적자 표현식에 대한 빌더를 제공합니다. 다른 모든 표현식은 JSON 형식 또는 호환되는 문서 형식으로 선언해야 합니다.
팁
다음 예시 중 하나의 구문은 $arrayElemAt 표현식을 정의합니다.
'categories' 앞의 $
는 이것이 필드 경로이며 입력 문서의 categories
필드를 사용한다는 것을 MongoDB에 알려줍니다.
new Document("$arrayElemAt", Arrays.asList("$categories", 0))
Document.parse("{ $arrayElemAt: ['$categories', 0] }")
또는 집계 표현식 작업 API를 사용하여 표현식을 구성할 수 있습니다. 자세한 내용은 집계 표현식 연산을 참조하세요.
다음 예시에서 집계 파이프라인은 $project
단계와 다양한 Projections
를 사용하여 name
필드와 categories
필드의 첫 번째 요소가 값인 계산된 필드 firstCategory
를 반환합니다.
collection.aggregate( Arrays.asList( Aggregates.project( Projections.fields( Projections.excludeId(), Projections.include("name"), Projections.computed( "firstCategory", new Document( "$arrayElemAt", Arrays.asList("$categories", 0) ) ) ) ) ) ).forEach(doc -> System.out.println(doc.toJson()));
앞의 집계는 다음과 같은 결과를 생성해야 합니다.
{"name": "456 Cookies Shop", "firstCategory": "Bakery"} {"name": "Sun Bakery Trattoria", "firstCategory": "Pizza"} {"name": "456 Steak Restaurant", "firstCategory": "Steak"} {"name": "Blue Bagels Grill", "firstCategory": "Bagels"} {"name": "XYZ Steak Buffet", "firstCategory": "Steak"} {"name": "Hot Bakery Cafe", "firstCategory": "Bakery"} {"name": "Green Feast Pizzeria", "firstCategory": "Pizza"} {"name": "ZZZ Pasta Buffet", "firstCategory": "Pasta"} {"name": "XYZ Coffee Bar", "firstCategory": "Coffee"} {"name": "XYZ Bagels Restaurant", "firstCategory": "Bagels"}
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.