Trước hết, bản đồ / thu nhỏ Mongo không được thiết kế để sử dụng như một công cụ truy vấn (như trong CouchDB), nó được thiết kế để bạn chạy các tác vụ nền. Tôi sử dụng nó tại nơi làm việc để phân tích dữ liệu lưu lượng truy cập.
Tuy nhiên, điều bạn đang làm sai là bạn đang áp dụng sort () cho đầu vào của mình, nhưng nó vô ích vì khi map()
giai đoạn được thực hiện, các tài liệu trung gian được sắp xếp theo từng khóa keys
. Vì khóa của bạn là tài liệu nên nó đang được sắp xếp theo product_id
, popularity
.
Đây là cách tôi tạo tập dữ liệu của mình
function generate_dummy_data() {
for (i=2; i < 1000000; i++) {
db.foobar.save({
_id: i,
category_id: parseInt(Math.random() * 30),
popularity: parseInt(Math.random() * 50)
})
}
}
Và đây là bản đồ / nhiệm vụ thu gọn của tôi:
var data = db.runCommand({
'mapreduce': 'foobar',
'map': function() {
emit({
sorting: this.popularity * -1,
product_id: this._id,
popularity: this.popularity,
}, 1);
},
'reduce': function(key, values) {
var sum = 0;
values.forEach(function(v) {
sum += v;
});
return sum;
},
'query': {category_id: 20},
'out': {inline: 1},
});
Và đây là kết quả cuối cùng (rất lâu để dán nó vào đây):
http://cesarodas.com/results.txt
Điều này hoạt động vì bây giờ chúng tôi đang sắp xếp theo sorting, product_id, popularity
. Bạn có thể chơi với cách sắp xếp bất cứ lúc nào bạn muốn chỉ cần nhớ rằng việc sắp xếp cuối cùng là theo key
bất kể bạn được sắp xếp như thế nào.
Dù sao như tôi đã nói trước đây, bạn nên tránh thực hiện các truy vấn với Map / Reduce, nó được thiết kế để xử lý nền. Nếu tôi là bạn, tôi sẽ thiết kế dữ liệu của mình theo cách mà tôi có thể truy cập nó bằng các truy vấn đơn giản, luôn có sự đánh đổi trong trường hợp này là chèn / cập nhật phức tạp để có các truy vấn đơn giản (đó là cách tôi thấy MongoDB).