MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

MongoDB Aggregations Sử dụng Java

1. Tổng quan

Trong hướng dẫn này, chúng ta sẽ đi sâu vào khuôn khổ Tổng hợp MongoDB sử dụng trình điều khiển Java MongoDB .

Đầu tiên chúng ta sẽ xem xét tổng hợp có nghĩa là gì về mặt khái niệm, sau đó thiết lập một tập dữ liệu. Cuối cùng, chúng ta sẽ thấy các kỹ thuật tổng hợp khác nhau đang hoạt động bằng cách sử dụng Trình tạo tổng hợp .

2. Tổng hợp là gì?

Tổng hợp được sử dụng trong MongoDB để phân tích dữ liệu và lấy thông tin có ý nghĩa từ đó .

Chúng thường được thực hiện trong các giai đoạn khác nhau và các giai đoạn tạo thành một đường dẫn - sao cho đầu ra của một giai đoạn được chuyển làm đầu vào cho giai đoạn tiếp theo.

Các giai đoạn thường được sử dụng nhất có thể được tóm tắt như sau:

Sân khấu SQL Tương đương Mô tả
dự án CHỌN chỉ chọn các trường bắt buộc, cũng có thể được sử dụng để tính toán và thêm các trường dẫn xuất vào bộ sưu tập
khớp WHERE lọc bộ sưu tập theo tiêu chí đã chỉ định
nhóm GROUP BY tập hợp dữ liệu đầu vào lại với nhau theo tiêu chí đã chỉ định (ví dụ:count, sum) để trả về một tài liệu cho mỗi nhóm riêng biệt
sắp xếp ĐẶT HÀNG THEO sắp xếp kết quả theo thứ tự tăng dần hoặc giảm dần của một trường nhất định
đếm COUNT đếm các tài liệu mà bộ sưu tập chứa
giới hạn LIMIT giới hạn kết quả ở một số tài liệu cụ thể, thay vì trả lại toàn bộ bộ sưu tập
ra CHỌN VÀO MỚI_TABLE ghi kết quả vào một tập hợp đã đặt tên; giai đoạn này chỉ được chấp nhận là giai đoạn cuối cùng trong quy trình


SQL tương đương cho mỗi giai đoạn tổng hợp được bao gồm ở trên để cung cấp cho chúng tôi ý tưởng về ý nghĩa của hoạt động đã nói trong thế giới SQL.

Chúng ta sẽ xem xét các mẫu mã Java cho tất cả các giai đoạn này ngay sau đây. Nhưng trước đó, chúng ta cần một cơ sở dữ liệu.

3. Thiết lập cơ sở dữ liệu

3.1. Tập dữ liệu

Yêu cầu đầu tiên và quan trọng nhất để học bất cứ thứ gì liên quan đến cơ sở dữ liệu là chính tập dữ liệu!

Với mục đích của hướng dẫn này, chúng tôi sẽ sử dụng một điểm cuối API khôi phục có sẵn công khai cung cấp thông tin toàn diện về tất cả các quốc gia trên thế giới. API này cung cấp cho chúng tôi rất nhiều điểm dữ liệu cho một quốc gia ở định dạng JSON thuận tiện . Một số trường mà chúng tôi sẽ sử dụng trong phân tích của mình là:

  • tên - tên quốc gia; ví dụ: Hợp chủng quốc Hoa Kỳ
  • Mã alpha3 - một mã viết tắt cho tên quốc gia; ví dụ: IND (dành cho Ấn Độ)
  • vùng - khu vực mà quốc gia thuộc về; ví dụ: Châu Âu
  • khu vực - khu vực địa lý của đất nước
  • ngôn ngữ - ngôn ngữ chính thức của quốc gia ở định dạng mảng; ví dụ: Tiếng Anh
  • đường viền - một loạt các alpha3Code của các quốc gia láng giềng s

Bây giờ chúng ta hãy xem cách chuyển đổi dữ liệu này thành một bộ sưu tập trong cơ sở dữ liệu MongoDB .

3.2. Đang nhập vào MongoDB

Trước tiên, chúng tôi cần nhấn điểm cuối API để lấy tất cả các quốc gia và lưu phản hồi cục bộ trong tệp JSON . Bước tiếp theo là nhập nó vào MongoDB bằng cách sử dụng mongoimport lệnh:

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

Quá trình nhập thành công sẽ cung cấp cho chúng tôi một bộ sưu tập với 250 tài liệu.

4. Các mẫu tổng hợp trong Java

Bây giờ chúng tôi đã có các cơ sở được đề cập, hãy cùng tìm ra một số thông tin chi tiết có ý nghĩa từ dữ liệu chúng tôi có cho tất cả các quốc gia . Chúng tôi sẽ sử dụng một số thử nghiệm JUnit cho mục đích này.

Nhưng trước khi làm điều đó, chúng ta cần tạo kết nối với cơ sở dữ liệu:

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

Trong tất cả các ví dụ tiếp theo, chúng tôi sẽ sử dụng Tổng thể lớp trợ giúp được cung cấp bởi trình điều khiển Java MongoDB.

Để các đoạn mã của chúng tôi dễ đọc hơn, chúng tôi có thể thêm nhập tĩnh:

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

4.1. trận đấu tính

Để bắt đầu, hãy bắt đầu với một cái gì đó đơn giản. Trước đó, chúng tôi đã lưu ý rằng tập dữ liệu chứa thông tin về các ngôn ngữ.

Bây giờ, giả sử chúng tôi muốn kiểm tra số lượng quốc gia trên thế giới nơi tiếng Anh là ngôn ngữ chính thức :

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

Ở đây, chúng tôi đang sử dụng hai giai đoạn trong quy trình tổng hợp của mình: đối sánh tính .

Trước tiên, chúng tôi lọc ra bộ sưu tập để chỉ đối sánh những tài liệu có chứa Tiếng Anh bằng ngôn ngữ của họ đồng ruộng. Những tài liệu này có thể được hình dung như một bộ sưu tập tạm thời hoặc trung gian trở thành đầu vào cho giai đoạn tiếp theo của chúng tôi, tính. Điều này đếm số lượng tài liệu trong giai đoạn trước.

Một điểm khác cần lưu ý trong mẫu này là việc sử dụng phương pháp đầu tiên . Vì chúng tôi biết rằng đầu ra của giai đoạn cuối cùng, tính , sẽ là một bản ghi duy nhất, đây là một cách đảm bảo để trích xuất tài liệu kết quả duy nhất.

4.2. nhóm (với sum ) và sắp xếp

Trong ví dụ này, mục tiêu của chúng tôi là tìm ra khu vực địa lý có chứa số lượng quốc gia tối đa :

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

Như được hiển nhiên, chúng tôi đang sử dụng nhóm sắp xếp để đạt được mục tiêu của chúng tôi tại đây .

Đầu tiên, chúng tôi thu thập số lượng quốc gia trong mỗi khu vực bằng cách tích lũy một tổng số lần xuất hiện của chúng trong một kiểm đếm. Điều này cung cấp cho chúng tôi một bộ sưu tập trung gian các tài liệu, mỗi tài liệu chứa hai trường:khu vực và kiểm đếm các quốc gia trong đó. Sau đó, chúng tôi sắp xếp nó theo thứ tự giảm dần và trích xuất tài liệu đầu tiên để cung cấp cho chúng tôi khu vực có các quốc gia tối đa.

4.3. sắp xếp, giới hạn, hết

Bây giờ, hãy sử dụng sắp xếp , giới hạn hết để trích xuất bảy quốc gia lớn nhất theo khu vực và viết chúng vào một bộ sưu tập mới :

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

Ở đây, trước tiên, chúng tôi sắp xếp bộ sưu tập đã cho theo thứ tự giảm dần của khu vực. Sau đó, chúng tôi đã sử dụng Giới hạn tổng hợp # phương pháp để giới hạn kết quả chỉ trong bảy tài liệu. Cuối cùng, chúng tôi đã sử dụng out giai đoạn giải mã hóa dữ liệu này thành một bộ sưu tập mới có tên là large_seven . Bộ sưu tập này hiện có thể được sử dụng theo cách giống như bất kỳ bộ sưu tập nào khác - ví dụ:để tìm nếu nó chứa Hoa Kỳ.

4.4. dự án, nhóm (với tối đa), đối sánh

Trong mẫu cuối cùng của chúng tôi, hãy thử một cái gì đó phức tạp hơn. Giả sử chúng tôi cần tìm hiểu xem mỗi quốc gia có bao nhiêu đường biên giới chia sẻ với các quốc gia khác và con số tối đa như vậy là bao nhiêu .

Bây giờ trong tập dữ liệu của chúng tôi, chúng tôi có một đường viền trường, là một danh sách mảng alpha3Code s cho tất cả các quốc gia có chung biên giới, nhưng không có bất kỳ trường nào trực tiếp cung cấp cho chúng tôi số liệu. Vì vậy, chúng tôi sẽ cần lấy số lượng borderingCountries sử dụng dự án :

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

Sau đó, như chúng ta đã thấy trước đây, chúng ta sẽ nhóm bộ sưu tập dự kiến ​​để tìm tối đa giá trị của borderingCountries . Một điều cần chỉ ra ở đây là tối đa bộ tích lũy cung cấp cho chúng tôi giá trị lớn nhất dưới dạng một số , không phải toàn bộ Tài liệu chứa giá trị lớn nhất. Chúng tôi cần thực hiện đối sánh để lọc ra Tài liệu mong muốn nếu cần thực hiện thêm bất kỳ hoạt động nào.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongo Câu hỏi truy vấn $ gt, $ lt

  2. So sánh mongoose _id và string

  3. Trường hợp cho chỉ số băm MongoDB

  4. Cách tìm giá trị tối thiểu trong mongodb

  5. Mongoose - Tên bộ sưu tập Force