MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB агрегации, използващи Java

1. Общ преглед

В този урок ще се потопим в рамката за агрегиране на MongoDB, използвайки драйвера MongoDB Java .

Първо ще разгледаме какво означава агрегирането концептуално и след това ще настроим набор от данни. И накрая, ще видим различни техники за агрегиране в действие с помощта на конструктора на агрегати .

2. Какво представляват агрегациите?

Агрегациите се използват в MongoDB за анализиране на данни и извличане на значима информация от тях .

Те обикновено се изпълняват на различни етапи и етапите образуват тръбопровод – така че изходът от един етап се предава като вход към следващия етап.

Най-често използваните етапи могат да бъдат обобщени като:

Етап Еквивалент на SQL Описание
 проект ИЗБЕРЕТЕ избира само задължителните полета, може също да се използва за изчисляване и добавяне на производни полета към колекцията
 съвпадение КЪДЕ филтрира колекцията според определени критерии
 група ГРУПИРА ПО събира въведените заедно според посочените критерии (напр. брой, сума), за да върне документ за всяко отделно групиране
 сортиране ПОРЪЧАЙ ПО сортира резултатите във възходящ или низходящ ред на дадено поле
 брой COUNT отброява документите, които колекцията съдържа
 лимит LIMIT ограничава резултата до определен брой документи, вместо да връща цялата колекция
 извън ИЗБЕРЕТЕ В НОВА_ТАБЛИЦА записва резултата в колекция с име; този етап е приемлив само като последен в конвейера


Еквивалентът на SQL за всеки етап на агрегиране е включен по-горе, за да ни даде представа какво означава споменатата операция в света на SQL.

Скоро ще разгледаме примерите на Java код за всички тези етапи. Но преди това имаме нужда от база данни.

3. Настройка на база данни

3.1. Набор от данни

Първото и основно изискване за изучаване на нещо, свързано с база данни, е самият набор от данни!

За целите на този урок ще използваме публично достъпна крайна точка на API, която предоставя изчерпателна информация за всички страни по света. Този API ни дава много точки от данни за държава в удобен JSON формат . Някои от полетата, които ще използваме в нашия анализ, са:

  • име – името на държавата; например Съединените американски щати
  • alpha3Code – кратък код за името на държавата; например IND (за Индия)
  • регион – регионът, към който принадлежи страната; например Европа
  • област – географската област на страната
  • езици – официални езици на страната във формат масив; например английски
  • граници – масив от alpha3Code на съседни държави с

Сега нека видим как да конвертирате тези данни в колекция в база данни на MongoDB .

3.2. Импортиране в MongoDB

Първо, трябва да натиснем крайната точка на API, за да получим всички държави и да запазим отговора локално в JSON файл . Следващата стъпка е да го импортирате в MongoDB с помощта на mongoimport команда:

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

Успешният импорт трябва да ни даде колекция с 250 документа.

4. Обобщаващи проби в Java

Сега, когато имаме покрити основите, нека да започнем да извличаме някои смислени прозрения от данните, които имаме за всички държави . Ще използваме няколко JUnit теста за тази цел.

Но преди да направим това, трябва да направим връзка с базата данни:

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

Във всички примери, които следват, ще използваме Агрегатите помощен клас, предоставен от драйвера на MongoDB Java.

За по-добра четливост на нашите фрагменти можем да добавим статичен импорт:

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"));
}

Тук използваме два етапа в нашия конвейер за агрегиране:съвпадение и брой .

Първо, филтрираме колекцията, за да съвпада само с онези документи, които съдържат английски на техните езици поле. Тези документи могат да се представят като временна или междинна колекция, която се превръща във вход за следващия ни етап, бройте. Това отчита броя на документите в предишния етап.

Друг момент, който трябва да се отбележи в тази извадка, е използването на метода първо . Тъй като знаем, че изходът от последния етап, 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"));
}

Както е очевидно, използваме група и сортиране да постигнем целта си тука .

Първо, събираме броя на държавите във всеки регион, като натрупваме сума на срещанията им в променлива отчет. Това ни дава междинна колекция от документи, всяка от които съдържа две полета:региона и броя на страните в него. След това го сортираме в низходящ ред и извличаме първия документ, за да ни даде региона с максимален брой държави.

4.3. сортиране, лимит, и извън

Сега нека използваме сортиране , ограничение и извън да извлечете седемте най-големи държави по площ и да ги запишете в нова колекцията :

@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 метод за ограничаване на резултата само до седем документа. Накрая използвахме извъна етап за десериализиране на тези данни в нова колекция, наречена largest_seven . Тази колекция вече може да се използва по същия начин като всяка друга – например за намиране ако съдържа САЩ.

4.4. проект, група (с максимум), съвпадение

В последната ни извадка нека опитаме нещо по-сложно. Да кажем, че трябва да разберем колко граници всяка страна споделя с другите и какъв е максималният такъв брой .

Сега в нашия набор от данни имаме граници поле, което е масив с списък alpha3Code s за всички граничещи държави на нацията, но няма поле, което директно ни дава броя. Така че ще трябва да извлечем броя на граничните държави използвайки проект :

@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 . Едно нещо, което трябва да се отбележи тук е, че макс. акумулатор ни дава максималната стойност като число , а не целия Документ съдържащи максималната стойност. Трябва да проведем съвпадение за да филтрирате желания Документ ако трябва да се извършат някакви допълнителни операции.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDb се изключва с код 100

  2. Как да използвате моделиране на данни MongoDB за подобряване на операциите с пропускателна способност

  3. MongoDB $avg Оператор на конвейер за агрегиране

  4. Геопространствена поддръжка в MongoDB

  5. Репликация на MongoDB в хибридна облачна среда