I need to filter multiple nested array object by using multi nested objects in aggregate using mongoose nodejs. I have mention sample record data from collection and multi filter objects.
I work with one e-commerce product listing view page. In this listing page we have lot of products with different kind of features. Here I need to filter that products by using that list of product feature.
Example:
I have 3 number of mobile phones with different kind of features, like Color, RAM, Storage. These features are placed inside "productfilter" array in the below sample collection record. I could selected multiple features to filter mobile phones like, i select color: Blue, gold and RAM: 6GB, 8GB. Here second product from sample product list data, need to get as per selected filter. Because color:Blue and RAM:6GB is matched along with "IsDefault: 'true'" in second product object from sample product list data
Here need to filter records based on filter request data and along with that need to check "isDefault" to be "true"
Sample collection records
[
{
"_id": "5d710f9950b94f237f04407b",
"productfilter": [
{
"_id": "5d8d29ae014da910c0de0799",
"specTitle": "Color",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de079d",
"specLabel": "Rose Gold",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-rose-gold-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de079c",
"specLabel": "Black",
"isDefault": "true",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de079b",
"specLabel": "Blue",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de079a",
"specLabel": "Red",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-red-6gb-64gb-redmi-note-6-pro"
}
]
},
{
"_id": "5d8d29ae014da910c0de0796",
"specTitle": "RAM",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de0798",
"specLabel": "4GB",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-4gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de0797",
"specLabel": "6GB",
"isDefault": "true",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
}
]
},
{
"_id": "5d8d29ae014da910c0de0794",
"specTitle": "Storage",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de0795",
"specLabel": "64GB",
"isDefault": "true",
"specContent": ""
}
]
}
]
},
{
"_id": "5d710fe050b94f237f04407e",
"productfilter": [
{
"_id": "5d8d29ae014da910c0de07a3",
"specTitle": "Color",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de07a7",
"specLabel": "Rose Gold",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-rose-gold-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de07a6",
"specLabel": "Black",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-black-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de07a5",
"specLabel": "Blue",
"isDefault": "true",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de07a4",
"specLabel": "Red",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-red-6gb-64gb-redmi-note-6-pro"
}
]
},
{
"_id": "5d8d29ae014da910c0de07a0",
"specTitle": "RAM",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de07a2",
"specLabel": "4GB",
"isDefault": "false",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-4gb-64gb-redmi-note-6-pro"
},
{
"_id": "5d8d29ae014da910c0de07a1",
"specLabel": "6GB",
"isDefault": "true",
"specContent": "mobiles-accessories-mobiles-redmi-redmi-redmi-note-6-pro-blue-6gb-64gb-redmi-note-6-pro"
}
]
},
{
"_id": "5d8d29ae014da910c0de079e",
"specTitle": "Storage",
"attributeOptions": [
{
"_id": "5d8d29ae014da910c0de079f",
"specLabel": "64GB",
"isDefault": "true",
"specContent": ""
}
]
}
]
}
]
Sample selected request data from filter option lists in product list view pages, to filter above records
{
"filter": {
"genericFilter": [
{
"specTitle": "Color",
"specLabel": [
"Blue",
"Gold",
"Rose Gold"
]
},
{
"specTitle": "RAM",
"specLabel": [
"6GB",
"8GB"
]
},
{
"specTitle": "Storage",
"specLabel": [
"64GB",
"256GB"
]
}
]
}
}
This can be done using Aggregation Pipeline as following
db.products.aggregate([
{
$unwind: "$productfilter"
},
{
$unwind: "$productfilter.attributeOptions"
},
{
$project: {
"specTitle": "$productfilter.specTitle",
"specLabel": "$productfilter.attributeOptions.specLabel",
"isDefault": "$productfilter.attributeOptions.isDefault",
_id:0
}
},
{
$group: {
"_id": "$specTitle",
"specLabel": {$addToSet: "$specLabel"}
}
},
{
$project: {
"specTitle": "$_id",
"specLabel": "$specLabel",
"isDefault": "$productfilter.attributeOptions.isDefault",
_id:0
}
},
])
Explanation:
productFilter
; it means dividing the document in multiple records for each value of productFilter
array itemattributeOptions
which was inside productFilter
specTitle
and creates a new field 'specLabel'(which utilizes $addToSet to make an array from all different 'specLabel' values.). As it's a set, it does not repeat the values if it's present.$project
to suit your needs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.