Home > Blockchain >  mongodb query to find the min price in array of objects
mongodb query to find the min price in array of objects

Time:03-03

My documents:

[{
"title": "lenovo x-100",
"brand": "lenovo",
"category": "laptops",
"variant": [{
    "price": 30000,
    "RAM": "4GB",
    "storage": "256GB",
    "screen": "full hd",
    "chip": "i3"
}, {
    "price": 35000,
    "RAM": "8GB",
    "storage": "512GB",
    "screen": "full hd",
    "chip": "i5"
}, {
    "price": 40000,
    "RAM": "12GB",
    "storage": "2TB",
    "screen": "uhd",
    "chip": "i7"
}],
"salesCount": 32,
"buysCount": 35,
"viewsCount": 60
},
{
"title": "samsung12",
"brand": "lenovo",
"category": "mobile phones",
"variant": [{
    "price": 11000,
    "RAM": "4GB",
    "ROM": "32GB"
}, {
    "price": 16000,
    "RAM": "6GB",
    "ROM": "64GB"
}, {
    "price": 21000,
    "RAM": "8GB",
    "ROM": "128GB"
}],
"salesCount": 48,
"buysCount": 39,
"viewsCount": 74
}

Expected output

{
 _id:"lenovo",
 minPrice:1100
}

I have tried this method of aggregation

[{
$match: {
    brand: 'lenovo'
}
}, {
 $group: {
    _id: '$brand',
    prices: {
        $min: '$variant.price'
    }
}
}, {
$unwind: {
    path: '$prices'
}
}, {
$group: {
    _id: '$_id',
    minPrice: {
        $min: '$prices'
    }
}
}]

I want to find the minimum price based on the brand, this query is returning the expected output but is there any better way to get the expected outcome because using $unwind operator in quite expensive in the sense it may take longer execution time, hoping for positive response.Thanks in advance.

CodePudding user response:

You can use $reduce to replace the second $group stage.

  1. $match

  2. $group - Push variant.price into new array and results nested array of array.

  3. $project:

    3.1. $reduce - Use to flatten the nested array from the result 2 by $concat the arrays into one.

    3.2. $min - Select min value from the result 3.1.

db.collection.aggregate([
  {
    $match: {
      brand: "lenovo"
    }
  },
  {
    $group: {
      _id: "$brand",
      prices: {
        $push: "$variant.price"
      }
    }
  },
  {
    $project: {
      _id: 1,
      minPrice: {
        $min: {
          "$reduce": {
            "input": "$prices",
            "initialValue": [],
            "in": {
              "$concatArrays": [
                "$$value",
                "$$this"
              ]
            }
          }
        }
      }
    }
  }
])

Sample Mongo Playground

  • Related