MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Agregacje MongoDB przy użyciu języka Java

1. Przegląd

W tym samouczku zagłębimy się w strukturę agregacji MongoDB przy użyciu sterownika MongoDB Java .

Najpierw przyjrzymy się, co oznacza agregacja koncepcyjnie, a następnie skonfigurujemy zestaw danych. Na koniec zobaczymy różne techniki agregacji w działaniu przy użyciu Kreatora agregatów .

2. Czym są agregacje?

Agregacje są używane w MongoDB do analizowania danych i uzyskiwania z nich istotnych informacji .

Są one zwykle wykonywane w różnych etapach, a etapy tworzą potok – tak, że dane wyjściowe z jednego etapu są przekazywane jako dane wejściowe do następnego etapu.

Najczęściej używane etapy można podsumować jako:

Stage odpowiednik SQL Opis
 projekt WYBIERZ wybiera tylko wymagane pola, może być również używany do obliczania i dodawania pól pochodnych do kolekcji
 dopasuj GDZIE filtruje kolekcję zgodnie z określonymi kryteriami
 grupa GRUPUJ WG zbiera dane wejściowe zgodnie z określonymi kryteriami (np. liczba, suma), aby zwrócić dokument dla każdego odrębnego grupowania
 sortuj ORDER BY sortuje wyniki w porządku rosnącym lub malejącym w danym polu
 liczba COUNT zlicza dokumenty, które zawiera kolekcja
 limit LIMIT ogranicza wynik do określonej liczby dokumentów, zamiast zwracać całą kolekcję
 out WYBIERZ DO NEW_TABLE zapisuje wynik do nazwanej kolekcji; ten etap jest akceptowalny tylko jako ostatni w potoku


Ekwiwalent SQL dla każdego etapu agregacji znajduje się powyżej, aby dać nam wyobrażenie o tym, co ta operacja oznacza w świecie SQL.

Niedługo przyjrzymy się przykładom kodu Java dla wszystkich tych etapów. Ale wcześniej potrzebujemy bazy danych.

3. Konfiguracja bazy danych

3.1. Zbiór danych

Pierwszym i najważniejszym wymogiem uczenia się czegokolwiek związanego z bazą danych jest sam zestaw danych!

Na potrzeby tego samouczka użyjemy publicznie dostępnego, spokojnego punktu końcowego interfejsu API, który zapewnia wyczerpujące informacje o wszystkich krajach świata. Ten interfejs API zapewnia nam wiele punktów danych dla kraju w wygodnym formacie JSON . Niektóre z pól, których będziemy używać w naszej analizie, to:

  • nazwisko – nazwa kraju; na przykład Stany Zjednoczone Ameryki
  • alpha3Code – skrócony kod do nazwy kraju; na przykład IND (dla Indii)
  • region – region, do którego należy kraj; na przykład Europa
  • obszar – obszar geograficzny kraju
  • języki – języki urzędowe kraju w formacie tablicowym; na przykład angielski
  • granice – tablica kodów alpha3Code sąsiednich krajów s

Zobaczmy teraz, jak przekonwertować te dane na kolekcję w bazie danych MongoDB .

3.2. Importowanie do MongoDB

Najpierw musimy trafić do punktu końcowego API, aby pobrać wszystkie kraje i zapisać odpowiedź lokalnie w pliku JSON . Następnym krokiem jest zaimportowanie go do MongoDB za pomocą mongoimport polecenie:

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

Pomyślny import powinien dać nam kolekcję zawierającą 250 dokumentów.

4. Próbki agregacji w Javie

Teraz, gdy mamy już omówione podstawy, przejdźmy do uzyskania pewnych istotnych informacji na podstawie danych, które mamy dla wszystkich krajów . W tym celu użyjemy kilku testów JUnit.

Ale zanim to zrobimy, musimy nawiązać połączenie z bazą danych:

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

We wszystkich poniższych przykładach będziemy używać agregatów klasa pomocnicza dostarczana przez sterownik MongoDB Java.

Dla lepszej czytelności naszych fragmentów możemy dodać statyczny import:

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

4.1. dopasuj i count

Na początek zacznijmy od czegoś prostego. Wcześniej zauważyliśmy, że zbiór danych zawiera informacje o językach.

Załóżmy teraz, że chcemy sprawdzić liczbę krajów na świecie, w których angielski jest językiem urzędowym :

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

W naszym potoku agregacji używamy dwóch etapów:match i count .

Najpierw odfiltrowujemy kolekcję, aby dopasować tylko te dokumenty, które zawierają język angielski w ich językach pole. Te dokumenty można sobie wyobrazić jako tymczasowy lub pośredni zbiór, który staje się danymi wejściowymi do naszego następnego etapu, count. Liczy to liczbę dokumentów na poprzednim etapie.

Inną kwestią, na którą należy zwrócić uwagę w tym przykładzie, jest użycie metody najpierw . Ponieważ wiemy, że wynik ostatniego etapu, count , będzie pojedynczym rekordem, jest to gwarantowany sposób wyodrębnienia pojedynczego dokumentu wynikowego.

4.2. grupa (z sumą ) i sortuj

W tym przykładzie naszym celem jest znalezienie regionu geograficznego zawierającego maksymalną liczbę krajów :

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

Jak widać, używamy grupy i sortuj aby osiągnąć nasz cel tutaj .

Najpierw zbieramy liczbę krajów w każdym regionie, gromadząc suma ich wystąpień w zmiennej tally. Daje nam to pośredni zbiór dokumentów, z których każdy zawiera dwa pola:region i listę krajów w nim zawartych. Następnie sortujemy go w kolejności malejącej i wyodrębniamy pierwszy dokument, aby dać nam region z maksymalną liczbą krajów.

4.3. sortuj, limit, i out

Teraz użyjmy sortowania , limit i out wyodrębnić siedem największych krajów pod względem obszaru i zapisać je w nowej kolekcji :

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

Tutaj najpierw posortowaliśmy daną kolekcję w porządku malejącym według obszaru Następnie użyliśmy Agregates#limit metoda ograniczająca wynik tylko do siedmiu dokumentów. Na koniec użyliśmy out etap, aby zdeserializować te dane do nowej kolekcji o nazwie largest_seven . Ta kolekcja może być teraz używana w taki sam sposób, jak każda inna – na przykład do znalezienia jeśli zawiera USA.

4.4. projekt, grupa (z maks.), dopasowanie

W naszym ostatnim przykładzie spróbujmy czegoś trudniejszego. Powiedzmy, że musimy sprawdzić, ile granic każdy kraj dzieli z innymi i jaka jest maksymalna taka liczba .

Teraz w naszym zbiorze danych mamy obramowania pole, które jest tablicą zawierającą listę alpha3Code s dla wszystkich sąsiadujących krajów narodu, ale nie ma żadnego pola, które bezpośrednio podałoby nam liczbę. Musimy więc ustalić liczbę krajów graniczących za pomocą projektu :

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

Następnie, jak widzieliśmy wcześniej, pogrupujemy przewidywaną kolekcję, aby znaleźć maks wartość borderingCountries . Należy tutaj podkreślić, że maks akumulator podaje nam maksymalną wartość w postaci liczby , a nie cały Dokument zawierające wartość maksymalną. Musimy wykonać dopasowanie aby odfiltrować żądany Dokument jeśli mają być wykonane jakiekolwiek dalsze operacje.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongoid Group By lub MongoDb group by w szynach

  2. MongoDB $pow

  3. MongoDB — Błąd:polecenie getMore nie powiodło się:nie znaleziono kursora

  4. Jak zmienić nazwę bazy danych MongoDB?

  5. Znajdź dokumenty w MongoDB, których pole tablicy jest podzbiorem tablicy zapytań