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

Dữ liệu mùa xuân MongoDB:Phép chiếu và Tổng hợp

1. Tổng quan

Dữ liệu mùa xuân MongoDB cung cấp các bản tóm tắt cấp cao đơn giản cho ngôn ngữ truy vấn gốc MongoDB. Trong bài viết này, chúng ta sẽ khám phá sự hỗ trợ cho khung Dự báo và Tổng hợp.

Nếu bạn chưa quen với chủ đề này, hãy tham khảo bài viết giới thiệu Giới thiệu về Spring Data MongoDB của chúng tôi.

2. Phép chiếu

Trong MongoDB, Phép chiếu là một cách để chỉ tìm nạp các trường bắt buộc của tài liệu từ cơ sở dữ liệu. Điều này làm giảm lượng dữ liệu phải được chuyển từ máy chủ cơ sở dữ liệu sang máy khách và do đó tăng hiệu suất.

Với Spring Data MongDB, các phép chiếu có thể được sử dụng cả với MongoTemplate MongoRepository.

Trước khi tiến xa hơn, hãy xem mô hình dữ liệu mà chúng tôi sẽ sử dụng:

@Document
public class User {
    @Id
    private String id;
    private String name;
    private Integer age;
    
    // standard getters and setters
}

2.1. Phép chiếu bằng MongoTemplate

Bao gồm () loại trừ () các phương pháp trên Trường lớp được sử dụng để bao gồm và loại trừ các trường tương ứng:

Query query = new Query();
query.fields().include("name").exclude("id");
List<User> john = mongoTemplate.find(query, User.class);

Các phương pháp này có thể được xâu chuỗi với nhau để bao gồm hoặc loại trừ nhiều trường. Trường được đánh dấu là @Id ( _id trong cơ sở dữ liệu) luôn được tìm nạp trừ khi bị loại trừ rõ ràng.

Các trường bị loại trừ là null trong cá thể lớp mô hình khi các bản ghi được tìm nạp bằng phép chiếu. Trong trường hợp các trường thuộc kiểu nguyên thủy hoặc lớp trình bao bọc của chúng, thì giá trị của các trường bị loại trừ là giá trị mặc định của kiểu nguyên thủy.

Ví dụ: Chuỗi sẽ là null , int / Số nguyên sẽ là 0 boolean / Boolean sẽ là sai .

Vì vậy, trong ví dụ trên, tên trường sẽ là John , id sẽ là null tuổi sẽ là 0.

2.2. Phép chiếu bằng MongoRepository

Trong khi sử dụng MongoRepositories, các trường trong tổng số @Query chú thích có thể được xác định ở định dạng JSON:

@Query(value="{}", fields="{name : 1, _id : 0}")
List<User> findNameAndExcludeId();

Kết quả sẽ giống như sử dụng MongoTemplate. value =”{}” biểu thị không có bộ lọc và do đó tất cả các tài liệu sẽ được tìm nạp.

3. Tổng hợp

Tính tổng hợp trong MongoDB được xây dựng để xử lý dữ liệu và trả về kết quả được tính toán. Dữ liệu được xử lý theo từng giai đoạn và đầu ra của một giai đoạn được cung cấp làm đầu vào cho giai đoạn tiếp theo. Khả năng áp dụng các phép biến đổi và tính toán trên dữ liệu theo từng giai đoạn làm cho việc tổng hợp trở thành một công cụ rất mạnh để phân tích.

Dữ liệu mùa xuân MongoDB cung cấp một sự trừu tượng cho các truy vấn tổng hợp gốc bằng cách sử dụng ba lớp Tổng hợp bao bọc một truy vấn tổng hợp, AggregationOperation bao gồm các giai đoạn đường ống riêng lẻ và AggregationResults là nơi chứa kết quả được tạo ra bằng cách tổng hợp.

Để thực hiện và tổng hợp, trước tiên, hãy tạo các đường ống tổng hợp bằng cách sử dụng các phương pháp của trình tạo tĩnh trên Tổng hợp lớp, sau đó tạo một bản sao của Tổng hợp bằng cách sử dụng newAggregation () phương pháp trên Tổng hợp và cuối cùng chạy tập hợp bằng MongoTemplate :

MatchOperation matchStage = Aggregation.match(new Criteria("foo").is("bar"));
ProjectionOperation projectStage = Aggregation.project("foo", "bar.baz");
        
Aggregation aggregation 
  = Aggregation.newAggregation(matchStage, projectStage);

AggregationResults<OutType> output 
  = mongoTemplate.aggregate(aggregation, "foobar", OutType.class);

Xin lưu ý rằng cả MatchOperation ProjectionOperation triển khai AggregationOperation . Có các cách triển khai tương tự cho các đường ống tổng hợp khác. OutType là mô hình dữ liệu cho đầu ra dự kiến.

Bây giờ, chúng ta sẽ xem xét một vài ví dụ và giải thích của chúng để đề cập đến các nhà khai thác và đường ống tổng hợp chính.

Tập dữ liệu mà chúng tôi sẽ sử dụng trong bài viết này liệt kê chi tiết về tất cả các mã zip ở Hoa Kỳ có thể được tải xuống từ kho lưu trữ MongoDB.

Hãy xem tài liệu mẫu sau khi nhập tài liệu đó vào bộ sưu tập có tên là zips trong bài kiểm tra cơ sở dữ liệu.

{
    "_id" : "01001",
    "city" : "AGAWAM",
    "loc" : [
        -72.622739,
        42.070206
    ],
    "pop" : 15338,
    "state" : "MA"
}

Vì mục đích đơn giản và để làm cho mã ngắn gọn, trong các đoạn mã tiếp theo, chúng tôi sẽ giả định rằng tất cả tĩnh các phương pháp của Tổng hợp lớp được nhập tĩnh.

3.1. Nhận tất cả các quốc gia có dân số trên 10 triệu đơn hàng theo dân số giảm dần

Ở đây chúng ta sẽ có ba đường ống:

  1. $ nhóm giai đoạn tổng hợp dân số của tất cả các mã zip
  2. $ match giai đoạn để lọc ra các tiểu bang có dân số hơn 10 triệu người
  3. $ sort giai đoạn sắp xếp tất cả các tài liệu theo thứ tự giảm dần của dân số

Đầu ra dự kiến ​​sẽ có trường _id dưới dạng trạng thái và một trường statePop với tổng dân số tiểu bang. Hãy tạo mô hình dữ liệu cho điều này và chạy tổng hợp:

public class StatePoulation {
 
    @Id
    private String state;
    private Integer statePop;
 
    // standard getters and setters
}

@Id chú thích sẽ ánh xạ _id trường từ đầu ra đến trạng thái trong mô hình:

GroupOperation groupByStateAndSumPop = group("state")
  .sum("pop").as("statePop");
MatchOperation filterStates = match(new Criteria("statePop").gt(10000000));
SortOperation sortByPopDesc = sort(Sort.by(Direction.DESC, "statePop"));

Aggregation aggregation = newAggregation(
  groupByStateAndSumPop, filterStates, sortByPopDesc);
AggregationResults<StatePopulation> result = mongoTemplate.aggregate(
  aggregation, "zips", StatePopulation.class);

Kết quả tổng hợp triển khai lớp Có thể lặp lại và do đó chúng tôi có thể lặp lại nó và in kết quả.

Nếu mô hình dữ liệu đầu ra không được biết, thì lớp MongoDB Tài liệu tiêu chuẩn có thể được sử dụng.

3.2. Có được Tiểu bang Nhỏ nhất theo Dân số Thành phố Trung bình

Đối với vấn đề này, chúng tôi sẽ cần bốn giai đoạn:

  1. $ nhóm để tính tổng dân số của mỗi thành phố
  2. $ nhóm để tính dân số trung bình của mỗi tiểu bang
  3. $ sort giai đoạn để sắp xếp các tiểu bang theo dân số thành phố trung bình của họ theo thứ tự tăng dần
  4. $ giới hạn để có được tiểu bang đầu tiên có dân số trung bình thấp nhất của thành phố

Mặc dù không nhất thiết phải bắt buộc, nhưng chúng tôi sẽ sử dụng thêm một $ project giai đoạn định dạng lại tài liệu theo StatePopulation mô hình dữ liệu.

GroupOperation sumTotalCityPop = group("state", "city")
  .sum("pop").as("cityPop");
GroupOperation averageStatePop = group("_id.state")
  .avg("cityPop").as("avgCityPop");
SortOperation sortByAvgPopAsc = sort(Sort.by(Direction.ASC, "avgCityPop"));
LimitOperation limitToOnlyFirstDoc = limit(1);
ProjectionOperation projectToMatchModel = project()
  .andExpression("_id").as("state")
  .andExpression("avgCityPop").as("statePop");

Aggregation aggregation = newAggregation(
  sumTotalCityPop, averageStatePop, sortByAvgPopAsc,
  limitToOnlyFirstDoc, projectToMatchModel);

AggregationResults<StatePopulation> result = mongoTemplate
  .aggregate(aggregation, "zips", StatePopulation.class);
StatePopulation smallestState = result.getUniqueMappedResult();

Trong ví dụ này, chúng ta đã biết rằng sẽ chỉ có một tài liệu trong kết quả vì chúng tôi giới hạn số lượng tài liệu đầu ra là 1 trong giai đoạn cuối. Như vậy, chúng tôi có thể gọi getUniqueMappedResult () để có được StatePopulation cần thiết ví dụ.

Một điều cần lưu ý khác là, thay vì dựa vào @Id chú thích cho bản đồ _id nói rõ, chúng tôi đã thực hiện một cách rõ ràng trong giai đoạn chiếu.

3.3. Nhận trạng thái với mã Zip tối đa và tối thiểu

Đối với ví dụ này, chúng ta cần ba giai đoạn:

  1. $ nhóm để đếm số lượng mã zip cho mỗi tiểu bang
  2. $ sort để sắp xếp các tiểu bang theo số lượng mã zip
  3. $ nhóm để tìm trạng thái có mã zip tối đa và tối thiểu bằng cách sử dụng $ first $ cuối cùng toán tử
GroupOperation sumZips = group("state").count().as("zipCount");
SortOperation sortByCount = sort(Direction.ASC, "zipCount");
GroupOperation groupFirstAndLast = group().first("_id").as("minZipState")
  .first("zipCount").as("minZipCount").last("_id").as("maxZipState")
  .last("zipCount").as("maxZipCount");

Aggregation aggregation = newAggregation(sumZips, sortByCount, groupFirstAndLast);

AggregationResults<Document> result = mongoTemplate
  .aggregate(aggregation, "zips", Document.class);
Document document= result.getUniqueMappedResult();

Ở đây chúng tôi chưa sử dụng bất kỳ mô hình nào nhưng sử dụng Tài liệu đã được cung cấp trình điều khiển MongoDB.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongoose kéo ObjectId từ mảng

  2. Lập chỉ mục trên một trường nằm trong một loạt các tài liệu con

  3. Sử dụng toán tử $ gte và <e mongo nếu ngày ở định dạng chuỗi trong mongodb

  4. Tính trung bình của một trường tài liệu phụ trên toàn bộ tài liệu trong Mongo

  5. Chuyển đổi một ngày được lưu trữ mongo trở lại thành mili giây kể từ kỷ nguyên Unix khi được tải?