Bạn có thể dễ dàng tổng hợp kết quả, thay vì chọn giải pháp thu nhỏ bản đồ:
-
Match
các bản ghi trong đó ngày lớn hơn ngày đã chỉ định. -
Group
dựa trênbrand_id
trường. -
Sử dụng $ addToSet nhà điều hành để duy trì một
products
danh sáchproduct_id
duy nhất cho mỗi nhóm. -
Project
số lượngcount
củaproducts
mảng trong mỗi khóa.
Mã:
db.collection.aggregate([
{$match:{"date":{$gte:new Date('2014-11-20')}}},
{$group:{"_id":"$brand_id","products":{$addToSet:"$product_id"}}},
{$project:{"_id":0,"brand_id":"$_id","distinct_prod":{$size:"$products"}}}
])
Đến với giải pháp thu nhỏ bản đồ của bạn,
Đó là một cách mongodb có thể gọi hàm giảm cho mỗi nhóm. Từ tài liệu :
Bạn cần thực hiện một số sửa đổi đối với map
, reduce
và thêm một finalize
mới chức năng:
- Bạn cần nhớ rằng khi
mongodb
gọireduce
cho cùng một khóa nhiều hơn một lần, kết quả của vị trí trước đó sẽ được chuyển làm đầu vào cho hàm giảm, cùng với các giá trị khác trong lần gọi hàm giảm tiếp theo. - Điểm đầu tiên, Vì vậy, bạn cần đảm bảo đầu vào cho hàm giảm và giá trị trả về từ hàm giảm được cấu trúc tương tự, để logic được viết bên trong hàm giảm có thể tùy ý xử lý giá trị trả về của chính nó trong các lần gọi trước đó.
- Vì chúng tôi sẽ không thể truy xuất số lượng các giá trị riêng biệt khi được gọi theo lô, những gì chúng tôi có thể làm là viết
reduce
chức năng tích lũyproduct_ids
riêng biệt cho mỗi khóa và viết mộtfinalize
hàm tính toán số lượng các giá trị duy nhất đó.
Mã:
db.collection.mapReduce(
function() {
// emitting the same structure returned by the reduce function.
emit(this.brand_id, {"prod_id":[this.product_id]});
},
function(key, values) {
// the return value would be a list of unique product_ids.
var res = {"prod_id":[]};
for(var i=0;i<values.length;i++)
{
for(var j=0;j<values[i].prod_id.length;j++){
if(res.prod_id.indexOf(values[i].prod_id[j]) == -1){
res.prod_id.push(values[i].prod_id[j]);
}
}}
return res;
},
{
query: {date: {$gte: new Date('2014-11-20')}},
out: "example",
finalize: function(key, reducedValue){
// it returns just the count
return reducedValue.prod_id.length;
}
}
)