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 đồ:
-
Matchcác bản ghi trong đó ngày lớn hơn ngày đã chỉ định. -
Groupdựa trênbrand_idtrường. -
Sử dụng $ addToSet nhà điều hành để duy trì một
productsdanh sáchproduct_idduy nhất cho mỗi nhóm. -
Projectsố lượngcountcủaproductsmả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
mongodbgọireducecho 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
reducechức năng tích lũyproduct_idsriêng biệt cho mỗi khóa và viết mộtfinalizehà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;
}
}
)