1. 개요

이 예제에서는 MongoDB Java 드라이버를 사용하여 MongoDB Aggregation 프레임워크를 살펴보겠습니다 .

먼저 집계가 개념적으로 무엇을 의미하는지 살펴본 다음 데이터 세트를 설정합니다. 마지막으로 Aggregates builder 를 사용하여 다양한 집계 기술이 작동하는 것을 볼 것 입니다.

2. 집계란 무엇입니까?

집계는 MongoDB에서 데이터를 분석하고 데이터에서 의미 있는 정보를 도출하는 데 사용됩니다 .

이들은 일반적으로 다양한 단계에서 수행되며 단계는 파이프라인을 형성하여 한 단계의 출력이 다음 단계의 입력으로 전달됩니다.

가장 일반적으로 사용되는 단계는 다음과 같이 요약할 수 있습니다.

단계 SQL 해당 설명
 프로젝트 선택하다 필수 필드만 선택하고 파생 필드를 계산하고 컬렉션에 추가하는 데 사용할 수도 있습니다.
 성냥 어디 지정된 기준에 따라 컬렉션을 필터링합니다.
 그룹 그룹화 기준 지정된 기준(예: 개수, 합계)에 따라 입력을 수집하여 개별 그룹별로 문서를 반환합니다.
 종류 주문 주어진 필드의 오름차순 또는 내림차순으로 결과를 정렬합니다.
 세다 세다 컬렉션에 포함된 문서를 계산합니다.
 한계 한계 전체 컬렉션을 반환하는 대신 지정된 수의 문서로 결과를 제한합니다.
  NEW_TABLE로 선택 결과를 명명된 컬렉션에 씁니다. 이 단계는 파이프라인의 마지막 단계로만 허용됩니다.


각 집계 단계에 해당 하는 SQL 이 위에 포함되어 SQL 세계에서 해당 작업이 의미하는 바를 알 수 있습니다.

이 모든 단계에 대한 Java 코드 샘플을 곧 살펴보겠습니다. 하지만 그 전에 데이터베이스가 필요합니다.

3. 데이터베이스 설정

3.1. 데이터세트

데이터베이스와 관련된 모든 것을 배우기 위한 첫 번째이자 가장 중요한 요구 사항은 데이터 세트 자체입니다!

이 사용방법(예제)의 목적 을 위해 전 세계 모든 국가에 대한 포괄적인 정보를 제공 하는 공개적으로 사용 가능한 restful API 엔드포인트 를 사용합니다. 이 API는 편리한 JSON 형식으로 국가에 대한 많은 데이터 포인트를 제공합니다 . 분석에 사용할 필드는 다음과 같습니다.

  • 이름 - 국가의 이름 예를 들어, 미국
  • alpha3Code – 국가 이름의 단축 코드입니다. 예: IND (인도의 경우)
  • 지역 - 국가가 속한 지역. 예를 들어  유럽
  • area – 국가의 지리적 영역
  • 언어 – 배열 형식의 국가 공식 언어 예를 들어, 영어
  • 국경 - 이웃 나라 '의 배열 alpha3Code의

이제 이 데이터를 MongoDB 데이터베이스의 컬렉션으로 변환하는 방법을 살펴보겠습니다 .

3.2. MongoDB로 가져오기

첫째, 우리는 할 필요가 히트 모든 국가를 얻을 수있는 API 엔드 포인트를 하고 JSON 파일에서 로컬 응답 저장 . 다음 단계는 mongoimport 명령을 사용하여 MongoDB로 가져오는 것입니다 .

mongoimport.exe --db <db_name> --collection <collection_name> --file <path_to_file> --jsonArray

성공적으로 가져오면 250개의 문서가 포함된 컬렉션이 제공됩니다.

4. 자바의 집계 샘플

이제 기반을 다뤘으므로 모든 국가에 대해 보유한 데이터에서 의미 있는 통찰력도출해 보겠습니다 . 이를 위해 여러 JUnit 테스트를 사용할 것입니다.

하지만 그렇게 하기 전에 데이터베이스에 연결해야 합니다.

@BeforeClass
public static void setUpDB() throws IOException {
    mongoClient = MongoClients.create();
    database = mongoClient.getDatabase(DATABASE);
    collection = database.getCollection(COLLECTION);
}

다음의 모든 예제 에서는 MongoDB Java 드라이버 에서 제공 하는 Aggregates 도우미 클래스를 사용할 것 입니다.

스니펫의 가독성을 높이기 위해 정적 가져오기를 추가할 수 있습니다.

import static com.mongodb.client.model.Aggregates.*;

4.1. 일치계산

우선 간단한 것부터 시작하겠습니다. 앞서 우리는 데이터 세트에 언어에 대한 정보가 포함되어 있음을 언급했습니다.

이제 영어가 공식 언어인 전 세계 국가의 수확인 하려고 한다고 가정해 보겠습니다 .

@Test
public void givenCountryCollection_whenEnglishSpeakingCountriesCounted_thenNinetyOne() {
    Document englishSpeakingCountries = collection.aggregate(Arrays.asList(
      match(Filters.eq("languages.name", "English")),
      count())).first();
    
    assertEquals(91, englishSpeakingCountries.get("count"));
}

여기에서는 집계 파이프라인에서 matchcount 의 두 단계를 사용 하고 있습니다.

첫째, 우리는 포함하는 문서 만 일치하는 컬렉션을 필터링 영어를 자신의 언어 필드. 이러한 문서는 다음 단계인 count에 대한 입력이 되는 임시 또는 중간 컬렉션으로 상상할 수 있습니다 . 이것은 이전 단계의 문서 수를 계산합니다.

이 샘플에서 주목해야 할 또 다른 점은 먼저 메서드를 사용한다는 것입니다 . 마지막 단계인 count 의 출력이 단일 레코드가 될 것이라는 것을 알고 있기 때문에 이것은 유일한 결과 문서를 추출하는 보장된 방법입니다.

4.2. 그룹화 ( 합계 포함 ) 및 정렬

이 예에서 우리의 목표는 최대 국가 수를 포함하는 지리적 지역찾는 것입니다 .

@Test
public void givenCountryCollection_whenCountedRegionWise_thenMaxInAfrica() {
    Document maxCountriedRegion = collection.aggregate(Arrays.asList(
      group("$region", Accumulators.sum("tally", 1)),
      sort(Sorts.descending("tally")))).first();
    
    assertTrue(maxCountriedRegion.containsValue("Africa"));
}

분명히 알 수 있듯이, 우리는 여기서 우리의 목적을 달성하기 위해 groupsort사용 하고 있습니다 .

먼저 변수 집계 에서 발생 합계누적하여 각 지역의 국가 수를 수집합니다 . 이렇게 하면 각각 두 개의 필드(지역 및 해당 국가의 집계)가 포함된 중간 문서 모음이 제공됩니다. 그런 다음 내림차순으로 정렬하고 첫 번째 문서를 추출하여 최대 국가가 있는 지역을 제공합니다.

4.3. 정렬, 제한제거

이제 sort , limitout 을 사용하여 영역별로 가장 큰 7개 국가를 추출하고 새 컬렉션에 작성해 보겠습니다 .

@Test
public void givenCountryCollection_whenAreaSortedDescending_thenSuccess() {
    collection.aggregate(Arrays.asList(
      sort(Sorts.descending("area")), 
      limit(7),
      out("largest_seven"))).toCollection();

    MongoCollection<Document> largestSeven = database.getCollection("largest_seven");

    assertEquals(7, largestSeven.countDocuments());

    Document usa = largestSeven.find(Filters.eq("alpha3Code", "USA")).first();

    assertNotNull(usa);
}

여기서는 먼저 주어진 컬렉션을 영역 의 내림차순으로 정렬했습니다 . 그런 다음 Aggregates#limit 메서드를 사용하여 결과를 7개의 문서로만 제한했습니다. 마지막으로 out 단계를 사용하여 이 데이터를 maximum_seven 이라는 새 컬렉션으로 역직렬화했습니다 . 이 컬렉션은 지금 다른과 같은 방법으로 사용할 수 있습니다 - 예를 들어,을 찾을 포함 된 경우 미국.

4.4. 프로젝트, 그룹(최대), 일치

마지막 샘플에서 더 까다로운 것을 시도해 보겠습니다. 각 국가가 다른 국가와 공유하는 국경의 수와 최대 국경 수 를 알아야 한다고 가정해 보겠습니다 .

이제 데이터 세트에 국경 필드 있습니다. 이 필드는 국가의 모든 국경 국가에 대한 alpha3Code 를 나열하는 배열 입니다. 하지만 직접적으로 개수를 알려주는 필드는 없습니다. 따라서 project를 사용하여 borderingCountries 의 수를 파생해야 합니다 .

@Test
public void givenCountryCollection_whenNeighborsCalculated_thenMaxIsFifteenInChina() {
    Bson borderingCountriesCollection = project(Projections.fields(Projections.excludeId(), 
      Projections.include("name"), Projections.computed("borderingCountries", 
        Projections.computed("$size", "$borders"))));
    
    int maxValue = collection.aggregate(Arrays.asList(borderingCountriesCollection, 
      group(null, Accumulators.max("max", "$borderingCountries"))))
      .first().getInteger("max");

    assertEquals(15, maxValue);

    Document maxNeighboredCountry = collection.aggregate(Arrays.asList(borderingCountriesCollection,
      match(Filters.eq("borderingCountries", maxValue)))).first();
       
    assertTrue(maxNeighboredCountry.containsValue("China"));
}

그 다음에는 이전에 보았듯이 예상 컬렉션을 그룹화 하여 borderingCountries최대을 찾습니다 . 여기에서 지적하는 한 가지이다 최대 축적이 우리에게 숫자로 최대 값을 제공 , 전체가 아닌 문서 의 최대 값을 포함합니다. 추가 작업이 수행되어야 하는 경우 원하는 문서 를 필터링 하기 위해 일치 를 수행해야 합니다 .

5. 결론

이 기사에서는 MongoDB 집계무엇이며 예제 데이터 세트를 사용하여 Java에 적용하는 방법을 보았습니다 .

개념에 대한 기본 이해를 형성하기 위해 다양한 집계 단계를 설명하기 위해 4개의 샘플을 사용했습니다. 이 프레임워크가 제공하는 데이터 분석의 가능성은 무궁무진합니다 .

추가 읽기를 위해 Spring Data MongoDBJava에서 프로젝션 및 집계 를 처리하는 대체 방법을 제공합니다 .

항상 그렇듯이 소스 코드는 GitHub에서 사용할 수 있습니다 .

Persistence footer banner