Search code examples
databasemongodbmapreducemongo-shell

How to find out number of elements in MongoDB array?


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.

enter image description here

enter image description here


Solution

  • 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
    }
    ])