Điều này tương tự như câu hỏi đã được hỏi trên Nhóm Google dành cho người dùng MongoDB.
https://groups.google.com/group/mongodb-user/browse_thread/thread/60a8b683e2626ada?pli=1
Câu trả lời đề cập đến một hướng dẫn trực tuyến trông giống với ví dụ của bạn:http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/
Để biết thêm thông tin về MapReduce trong MongoDB, vui lòng xem tài liệu:http://www.mongodb.org/display/DOCS/MapReduce
Ngoài ra, có một hướng dẫn từng bước hữu ích về cách hoạt động của hoạt động MapReduce trong Phần "Bổ sung" của bài viết MongoDB Cookbook có tiêu đề "Tìm Giá trị Tối đa và Tối thiểu với Tài liệu Phiên bản":http://cookbook.mongodb. org / pattern / seek_max_and_min /
Thứ lỗi cho tôi nếu bạn đã đọc một số tài liệu tham khảo. Tôi đã đưa chúng vào vì lợi ích của những người dùng khác có thể đang đọc bài đăng này và mới sử dụng MapReduce trong MongoDB
Điều quan trọng là các kết quả đầu ra từ các câu lệnh 'phát ra' trong các hàm Bản đồ phải khớp với các kết quả đầu ra của hàm Reduce. Nếu chỉ có một đầu ra tài liệu bởi chức năng Bản đồ, chức năng Rút gọn có thể hoàn toàn không chạy và khi đó bộ sưu tập đầu ra của bạn sẽ có các tài liệu không khớp.
Tôi đã sửa đổi một chút câu lệnh bản đồ của bạn để phát ra tài liệu ở định dạng đầu ra mong muốn của bạn, với hai mảng "lớp" riêng biệt.
Tôi cũng đã làm lại câu lệnh rút gọn của bạn để thêm lớp mới vào mảng lớp_1 và lớp_2, chỉ khi chúng chưa tồn tại.
var mapDetails = function(){
var output = {studentid: this.studentid, classes_1: [], classes_2: [], year: this.year, overall: 0, subscore: 0}
if (this.year == 1) {
output.classes_1 = this.classes;
}
if (this.year == 2) {
output.classes_2 = this.classes;
}
emit(this.studentid, output);
};
var mapGpas = function() {
emit(this.studentid, {studentid: this.studentid, classes_1: [], classes_2: [], year: 0, overall: this.overall, subscore: this.subscore});
};
var r = function(key, values) {
var outs = { studentid: "0", classes_1: [], classes_2: [], overall: 0, subscore: 0};
values.forEach(function(v){
outs.studentid = v.studentid;
v.classes_1.forEach(function(class){if(outs.classes_1.indexOf(class)==-1){outs.classes_1.push(class)}})
v.classes_2.forEach(function(class){if(outs.classes_2.indexOf(class)==-1){outs.classes_2.push(class)}})
if (v.year == 0) {
outs.overall = v.overall;
outs.subscore = v.subscore;
}
});
return outs;
};
res = db.details.mapReduce(mapDetails, r, {out: {reduce: 'joined'}})
res = db.gpas.mapReduce(mapGpas, r, {out: {reduce: 'joined'}})
Chạy hai hoạt động MapReduce sẽ tạo ra bộ sưu tập sau, phù hợp với định dạng mong muốn của bạn:
> db.joined.find()
{ "_id" : "12345a", "value" : { "studentid" : "12345a", "classes_1" : [ 1, 17, 19, 21 ], "classes_2" : [ 32, 91, 101, 217 ], "overall" : 97, "subscore" : 1 } }
{ "_id" : "24680a", "value" : { "studentid" : "24680a", "classes_1" : [ 1, 11, 18, 22 ], "classes_2" : [ ], "overall" : 76, "subscore" : 2 } }
{ "_id" : "98765a", "value" : { "studentid" : "98765a", "classes_1" : [ 2, 12, 19, 22 ], "classes_2" : [ 32, 99, 110, 215 ], "overall" : 85, "subscore" : 5 } }
>
MapReduce luôn xuất các tài liệu ở dạng {_id:"id", value:"value"} Có thêm thông tin về cách làm việc với các tài liệu con trong tài liệu có tiêu đề "Dấu chấm (Tiếp cận các đối tượng)":http:/ /www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
Nếu bạn muốn đầu ra của MapReduce xuất hiện ở một định dạng khác, bạn sẽ phải thực hiện điều đó theo chương trình trong ứng dụng của mình.
Hy vọng rằng điều này sẽ nâng cao hiểu biết của bạn về MapReduce và giúp bạn tiến gần hơn đến việc tạo ra bộ sưu tập đầu ra mong muốn của mình. Chúc may mắn!