MongoDB - Map Reduce: Hướng dẫn cho người mới bắt đầu

Xin chào các bạn tương lai trở thành những chuyên gia MongoDB! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của Map Reduce trong MongoDB. Đừng lo lắng nếu bạn là người mới bắt đầu lập trình - tôi sẽ là người hướng dẫn thân thiện của bạn, giải thích từng bước một. Vậy, hãy lấy một tách cà phê, và chúng ta cùng bắt đầu nhé!

MongoDB - Map Reduce

Map Reduce là gì?

Trước khi chúng ta nhảy vào các chi tiết cụ thể của MongoDB, hãy hiểu.Map Reduce là gì. Hãy tưởng tượng bạn đang cố đếm xem bạn có bao nhiêu viên bi đỏ, xanh và xanh trong một túi lớn. Map Reduce giống như việc có một nhóm bạn giúp bạn:

  1. Một người bạn (người map) lấy ra các viên bi và gọi to màu của chúng.
  2. Những người bạn khác (người reduce) mỗi người đếm một màu.
  3. Cuối cùng, bạn sẽ có tổng số đếm cho mỗi màu.

Đó là Map Reduce trong một câu ngắn gọn - nó là một cách để xử lý và tóm tắt một lượng lớn dữ liệu một cách hiệu quả.

Lệnh MapReduce trong MongoDB

Bây giờ, hãy xem chúng ta có thể sử dụng Map Reduce như thế nào trong MongoDB. Cấu trúc cơ bản của một hoạt động Map Reduce trong MongoDB trông như thế này:

db.collection.mapReduce(
function() { emit(key, value); },  // hàm map
function(key, values) { return reduceFunction; },  // hàm reduce
{
out: <output>,
query: <query>,
sort: <sort>,
limit: <limit>
}
)

Đừng lo lắng nếu điều này trông có vẻ rắc rối - chúng ta sẽ phân tích nó từng phần!

Hàm Map

Hàm map là nơi chúng ta quyết định dữ liệu nào chúng ta muốn xử lý. Nó giống như người bạn của bạn gọi to màu của các viên bi. Cho mỗi tài liệu, chúng ta sử dụng hàm emit() để xuất ra một khóa và một giá trị.

Giả sử chúng ta có một bộ sưu tập sách, và chúng ta muốn đếm xem mỗi tác giả đã viết bao nhiêu sách:

function() {
emit(this.author, 1);
}

Hàm này có nghĩa là, "cho mỗi sách, gọi to tên tác giả và số 1."

Hàm Reduce

Hàm reduce nhận tất cả các giá trị được phát ra cho một khóa cụ thể và kết hợp chúng. Nó giống như những người bạn của bạn đếm từng màu.

Đối với ví dụ về sách của chúng ta:

function(key, values) {
return Array.sum(values);
}

Hàm này có nghĩa là, "tAKE tất cả các 1 cho mỗi tác giả và cộng chúng lại."

Tùy chọn

Đối tượng tùy chọn cho phép chúng ta tùy chỉnh hoạt động Map Reduce của mình:

  • out: Địa điểm để lưu trữ kết quả
  • query: Lọc các tài liệu đầu vào
  • sort: Sắp xếp các tài liệu đầu vào
  • limit: Giới hạn số lượng tài liệu để xử lý

Sử dụng MapReduce

Bây giờ, hãy kết hợp tất cả lại với một ví dụ thực tế. Giả sử chúng ta có một bộ sưu tập dữ liệu bán hàng, và chúng ta muốn tính tổng doanh số cho mỗi sản phẩm.

Đầu tiên, hãy tạo một số dữ liệu mẫu:

db.sales.insertMany([
{ product: "Widget A", quantity: 5, price: 10 },
{ product: "Gadget B", quantity: 2, price: 20 },
{ product: "Widget A", quantity: 3, price: 10 },
{ product: "Gizmo C", quantity: 1, price: 30 },
{ product: "Gadget B", quantity: 4, price: 20 }
]);

Bây giờ, hãy sử dụng Map Reduce để tính tổng doanh số:

db.sales.mapReduce(
// Hàm map
function() {
emit(this.product, this.quantity * this.price);
},
// Hàm reduce
function(key, values) {
return Array.sum(values);
},
// Tùy chọn
{
out: "product_sales"
}
)

Hãy phân tích điều này:

  1. Hàm map tính doanh số bán hàng cho mỗi tài liệu và phát ra tên sản phẩm làm khóa.
  2. Hàm reduce cộng tổng tất cả các doanh số bán hàng cho mỗi sản phẩm.
  3. Chúng ta lưu kết quả trong một bộ sưu tập mới gọi là "product_sales".

Để xem kết quả:

db.product_sales.find()

Bạn có thể thấy điều này:

{ "_id" : "Widget A", "value" : 80 }
{ "_id" : "Gadget B", "value" : 120 }
{ "_id" : "Gizmo C", "value" : 30 }

Voilà! Chúng ta đã thành công sử dụng Map Reduce để tính tổng doanh số cho mỗi sản phẩm.

Khi nào nên sử dụng Map Reduce

Map Reduce rất mạnh mẽ, nhưng nó không phải lúc nào cũng là công cụ tốt nhất cho công việc. Dưới đây là một số tình huống mà Map Reduce tỏa sáng:

  1. Các phép tổng hợp phức tạp mà không thể thực hiện bằng pipeline tổng hợp
  2. Khi bạn cần xử lý một lượng lớn dữ liệu không phù hợp trong bộ nhớ
  3. Khi bạn cần thực hiện các hoạt động không có sẵn trong ngôn ngữ truy vấn của MongoDB

Tuy nhiên, đối với các nhiệm vụ đơn giản hơn, pipeline tổng hợp của MongoDB thường nhanh hơn và dễ sử dụng hơn.

Kết luận

Chúc mừng! Bạn đã bước đầu vào thế giới của Map Reduce trong MongoDB. Chúng ta đã bao gồm các основы, nhưng vẫn còn rất nhiều điều để khám phá. Nhớ rằng, như việc học骑 một chiếc xe đạp, việc thành thạo Map Reduce đòi hỏi phải thực hành. Đừng sợ thử nghiệm và mắc lỗi - đó là cách chúng ta học!

Khi chúng ta kết thúc, đây là bảng tóm tắt các thành phần chính của một hoạt động Map Reduce:

Thành phần Mô tả Ví dụ
Hàm Map Xử lý mỗi tài liệu và phát ra các cặp khóa-giá trị function() { emit(this.author, 1); }
Hàm Reduce Kết hợp các giá trị cho mỗi khóa function(key, values) { return Array.sum(values); }
Out Xác định nơi lưu trữ kết quả { out: "product_sales" }
Query Lọc các tài liệu đầu vào { query: { price: { $gt: 10 } } }
Sort Sắp xếp các tài liệu đầu vào { sort: { price: 1 } }
Limit Giới hạn số lượng tài liệu để xử lý { limit: 1000 }

Tiếp tục thực hành, giữ vững sự tò mò, và trước khi bạn biết, bạn sẽ trở thành một phù thủy Map Reduce! Chúc bạn may mắn với mã code của mình!

Credits: Image by storyset