Tuesday, 11 May 2021

MongoDB/JS - Advanced Faceted search - How to get only relevant categories/values

First of all thank you for opening my question. Before I write the actual question I write some details related to my project to fully understand what I want to achieve.

I have Product collection. In this collection each document has different keys and values (the datas are dynamic). On the example below the first two document has the same keys but the values are different, and the third document is missing the key:'Color':

{
_id:1
MainCategory:Vehicle
SubCategory:Car
Model:BMW
Color:Black
}

{
_id:2
MainCategory:Vehicle
SubCategory:Car
Model:Audi
Color:Red
}

{
_id:3
MainCategory:Vehicle
SubCategory:Car
Model:BMW
}

I have a Category collection this is based on MainCategory+SubCategory and here I store the keys and values, this will be used for a better filtering speed/experience.

_id:..
MainCategory:Vehicle
SubCategory:Car
Fields:{
        Model: {BMW:[_id1,_id3], Audi:[_id2]},
        Color: {Black:[_id1],Red:[_id2]}
       }

I want to make a filtering option based on Category collection, where all of the 'Fields' keys will be the filtering categories, and the values what these keys have will be the filtering options. The example above is the initial filtering state:

MainCategory-Vehicle
SubCategory-Car
Model - BMW, Audi
Color - Black, Red

And now here comes the question part: If a user selects the Model=BMW I want to retrieve only the relevant categories and values from my Category collection. In this case relevant means the following steps:

1.From Fields->Model->BMW I want to get the array of products which has the category value BMW -> i will get [_id1,_id3] . This will be the data which I will show on my UI.

The Advanced Part: 2.When I get the IDs I want to check if other objects from 'Fields' are containing any of the products from the above list:in this case the Fields->Color->Black contains the _id1

3.If an object is containing one of my products I want to retrieve the key as filtering category -> Color and the value which contained it -> Red

After this I will want to get the output something like this:

Products:[_id1,_id3]
Model:[BMW]
Color:[Black]

By this my filtering will show only the relevant categories and values and will look like this:

MainCategory:Car
SubCategory:Vehicle
Model: BMW
Color:Black

Example 2 Another example and this part makes hard to achieve the given output is: If a user selects the Color:Red value I want to retrieve the _id2 product and get from the Model only the 'Audi' value previously.

So in this case the filtering will look like:

Product:[_id2]
Model:Audi
Color:Red

Example 3 A third problem can be when a user selects more than one filtering category-value. For example if BMW has an addiotnal _id4, and _id4 is present in Color Red too. If a user selects Model:BMW and Color:Red for filtering option, we should join at the final output the BMW id array with the Red id array to get back only the BMW and Red options.

This case the filtering:

Product [_id1,_id3,_id4]
Model:BMW
Color:Red

How can I achieve to find the array in my object and check inside that object if any of the array values are present in other arrays? Is it possible to do it with only one query or it would be optimal to make two queries? Thanks in advance.

Update: Just an additional question: Is this kind of data structuring is good for Category collection or maybe I should think in totally other structure? Maybe can you advice something else for handling easier and faster the data?

Update2

//Product creation part -> the productbod contains the above mentioned key-value pairs

export const createProduct = async (productbod) => {
    try {
        if (!ObjectID.isValid(productbod.userId)) throw 'Invalid MongoDB ID.'
        const db=getDB()
        const product= db.collection('products')
    
        const finalProduct = await product.insertOne(productbod)
        return finalProduct
        
    } catch (err) {
        throw error
    }
}


from MongoDB/JS - Advanced Faceted search - How to get only relevant categories/values

No comments:

Post a Comment