My collection of products consists of _id
, product/title
, product/price
and reviews
. Reviews
is an array with all reviews for that specific product. I am trying to print out 10 products with the largest number of reviews but can't find the right solution.
This is what I tried so far:
var mapFunction = function() {
emit(this._id, {
product: this,
count_reviews: this.reviews.length
});
};
var reduceFunction = function(key, values) {
var count = 0;
var product;
values.forEach(function(value) {
count = value.count_reviews;
product = value.product
});
return { count_reviews: count, product: product};
};
db.products.mapReduce(mapFunction, reduceFunction, {
out: { inline: 1},
query: {},
sort: { count_reviews: -1 },
limit: 10
});
When I run this code it prints out 10 elements, but not with the largest number of reviews.
CodePudding user response:
I wouldn't use mapReduce (unless you're on a version so old you have to)
I'd use an aggregation, if you have strict data - you can omit the $match
, if you have "strictish" data (e.g., it's an array or missing) you can use a simpler match: { reviews: { $exists: true } }
db.products.aggregate([
{
$match: {
"value.reviews": { $type: "array" }
}
},
{
$set: { review_count: { $size: "$value.reviews" } }
},
{
$sort: { review_count: -1 },
},
{
$limit: 10
}
])