Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB percent of non-matching values in array

I have an array that contains objects with values, such as:

[{
  item: '123A',
  meta: {}
},
{
  item: '123A',
  meta: {}
},
{
  item: '123B',
  meta: {}
}
,{
  item: '123A',
  meta: {}
}]

I'm wondering if there's a way that I could query the percent highest percentage of same matching items.

For example, in this case the highest matching item is 123A, so I would want to return the percent of this item as it's found in the array, which would be 0.75.

I'd like to be able to query this, so I can ultimately sort by the lowest percent or highest percent.

I'm thinking there must be a way with aggregation, but I'm really not sure.

Any suggestions would be awesome.

like image 598
dzm Avatar asked Jan 25 '26 18:01

dzm


1 Answers

Possible with aggregation but you'd need to include an $unwind operator before the $group step to normalize/flatten your array so that you can carry out the necessary aggregations using the $group operator.

Consider the following aggregation operation that will give you the percentages computation in the final result, this supposes your documents have the bare minimum schema example:

{
    _id: 1,
    arr: [
        {  item: '123A',  meta: {} },
        {  item: '123A',  meta: {} },
        {  item: '123B',  meta: {} },
        {  item: '123A',  meta: {} }
    ]
}

Run the pipeline

var pipeline = [
        {
            "$project": {
                "arr": 1,
                "arrSize": { "$size": "$arr" }
            }
        },
        { "$unwind": "$arr" },      
        {
            "$group": {
                "_id": "$arr.item",
                "count": { "$sum": 1 },
                "total": { "$first": "$arrSize" }
            }
        },
        {
            "$project": {
                "item": "$_id",
                "_id": 0,
                "percentage":{
                    "$multiply": [
                        { "$divide": [ 100, "$total" ] }, "$count"
                    ]
                }
            }
        }
    ];
db.test.aggregate(pipeline);

Sample Output

{ "item" : "123A", "percentage" : 75 }
{ "item" : "123B", "percentage" : 25 }
like image 159
chridam Avatar answered Jan 28 '26 09:01

chridam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!