'How to get the json object with only 2 or more bananas in the fruits array?

I have this mongoose schema.

const storeSchema = mongoose.Schema({
    name: {
        type: String,
        required: true,
    },
    fruits: {
        type: [String],
        required: true,
    },
});

And I need to get all the objects that have 2 or more bananas in the fruits array, like this.

{
    "name": "Beautiful Store",
    "fruits": ["banana", "apple", "banana", "pear"]
}

I was trying something like this, but with no success...

const query = await StoreModel.find({ fruits: { $gd: 2 } })


Solution 1:[1]

Here are two variations on the theme.

The first uses $reduce to directly count the number of bananas (essentially, the {$size:{$filter...}} as above. For extra performance, we bring the calc and the $match together into a single stage:

db.foo.aggregate([
    {$match: {$expr: {$gte: [
        {$reduce: {
            input: '$fruits',
            initialValue: 0,
                in: {$cond:[{$eq: ['$$this','banana']}, {$add:['$$value',1]}, '$$value']}
        }}, 2]}
    }}
]);

The second is a general purpose fruit counter in case you want to have more complex expressions, e.g. >=2 bananas or (1 pear and 1 apple). It does come at a cost of $unwind/$group.

c=db.foo.aggregate([
    {$unwind: '$fruits'}
    ,{$group: {_id: {id: '$_id', f: '$fruits'}, N: {$sum:1}}}

    ,{$match: {'_id.f': 'banana', N:{$gte:2}} }
]);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Buzz Moschetti