Tìm hiểu các MongoDB aggregation operator hay dùng

Tram Ho

1. Aggregation overview

Aggregation là một framework tổng hợp dữ liệu của MongoDB. Aggregation được xây dựng dựa trên mô hình xử lý dữ liệu dưới dạng pipeline. Aggregation pipeline bao gồm nhiều stage. Trong mỗi stage, chúng ta sử dụng một aggregation operator để biến đổi dữ liệu của các input document. Các output document của stage phía trước sẽ là input document của stage ngay sau. Các aggregation operator có thể được sử dụng nhiều lần trong pipeline, ngoại trừ $out, $merge, và $geoNear.

Điểm mạnh của aggregation framework là:

  • Xử lý nhanh và mạnh mẽ với lượng ít băng thông.
  • Giải quyết được các yêu cầu phức tạp.
  • Có thể làm việc với dữ liệu lớn.

MongoDB cung cấp phương thức db.collection.aggregate() để chạy aggregation pipeline.

Cú pháp:

Trong đó:

  • Các stage được đặt trong một array theo thứ tự thực hiện trước sau.
  • Các option là tùy chọn, không nhất thiết phải có.

Để minh họa cho các operator, mình sẽ sử dụng 2 collection là orderscustomers.

Collection orders:

Collection customers:


2. $match

$match được dùng để lọc các document theo một điều kiện nào đó. $match tương tự như WHEREHAVING trong SQL.

Cú pháp:

Cú pháp query của $match y hệt cú pháp của read operation query (tương tự như find()).

Ví dụ:

Lọc các order của customer có ID là A123:

=> Kết quả:


3. $project

$project được dùng để chỉ định các field sẽ xuất hiện trong output document. Đó có thể là các field đã tồn tại trong input document, hoặc cũng có thể là các field được tính toán mới. $project tương tự như SELECT trong SQL.

Cú pháp:

Trong đó:

specification có thể có các dạng sau:

  • _id: <0 or false>: field _id sẽ không xuất hiện trong output document (mặc định _id luôn xuất hiện trong output document).
  • <field X>: <1 or true>: field X sẽ xuất hiện trong output document.
  • <field X>: <expression>: field X sẽ được tính toán dựa trên một expression nào đó.

Ví dụ:

=> Kết quả:


4. $count

$count mới xuất hiện trong MongoDB version 3.4. $count trả về thêm trong output một field X chứa tổng số input document.

Cú pháp:

Trong đó:

<string> là tên của field X, phải khác rỗng, không được bắt đầu bằng ký tự $ và không được bao gồm ký tự ..

Ví dụ:

=> Kết quả:


5. $limit$skip

$limit được dùng để giới hạn số lượng output document. $skip được dùng để chỉ định số lượng document sẽ bị bỏ qua trong output (tính từ document đầu tiên). $limit$skip tương tự như LIMITOFFSET trong SQL.

Cú pháp:

Ví dụ:

Lấy order thứ 3 và thứ 4:

=> Kết quả:


6. $sort

$sort được dùng để sắp xếp các document trong output theo một tiêu chí nào đó. $sort tương tự như ORDER BY trong SQL.

Cú pháp:

Trong đó, <sort order> có thể có các giá trị sau:

  • 1: sắp xếp theo thứ tự tăng dần
  • -1: sắp xếp theo thứ tự giảm dần

Ví dụ:

Sắp xếp các order theo thứ tự giảm dần của amount:

=> Kết quả:


7. $group

$group được dùng để gom nhóm các input document theo expression _id. Mỗi nhóm tương ứng với một output document. Trong $group, chúng ta có thể sử dụng các accumulator expression như $sum, $avg, $max, $min, …

$group tương tự như GROUP BY trong SQL.

Cú pháp:

Nếu _id được set bằng null, MongoDB sẽ query tất cả các input document.

Ví dụ:

Gom nhóm các order theo cust_id, đồng thời tính tổng amount của từng cust_id:

=> Kết quả:


8. $unwind

$unwind được dùng để phân tách giá trị của một array field trong các input document. Nếu như array field của một input document có N phần tử thì trong output sẽ có N document.

Cú pháp:

Ví dụ:

Mình sẽ thử áp dụng $unwind với array field products để xem kết quả nó sẽ như thế nào:

=> Kết quả:


9. $lookup

$lookup cho phép chúng ta thực hiện một phép left outer join giữa hai collection trong cùng một database. Với mỗi input document, $lookup sẽ thêm một array field chứa các phần tử matching với collection được join.

Cú pháp:

Trong đó:

  • from collection không thể bị shard.
  • as có thể có tên bất kỳ, nhưng nếu một field nào đó trong document đã có tên như vậy thì giá trị của field đó sẽ bị ghi đè.

$lookup tương đương với đoạn SQL sau:

Ví dụ:

Mình sẽ join orderscustomers để bổ sung thêm thông tin của customer trong từng order:

=> Kết quả:


10. Kết hợp các aggregation operator

Trong phần này, chúng ta sẽ kết hợp các aggregation operator trong một pipeline. Mình sẽ minh họa thông qua 2 ví dụ.

Ví dụ 1

Yêu cầu:

  1. Lọc tất cả các order có statuscompleted.
  2. Gom nhóm các order có được ở bước 1 theo cust_id và tính tổng amount.
  3. Sắp xếp theo tổng amount giảm dần.

=> Kết quả:

Ví dụ 2

Tiếp tục ví dụ 1, chúng ta sẽ bổ sung thêm customer name cho các output document. Các bạn lưu ý chúng ta sẽ chỉ bổ sung customer name mà thôi, còn customer ID thì chúng ta đã lưu trong _id rồi.

=> Kết quả:

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo