How to model this simple but somewhat complex data

I’ve been thinking how to model this for a while, but can’t seem to get how. Here is how the data is: There are 4 electronics types, namely:Mobiles, Laptops, Mobile Accessories and Other They include the following:

  1. Mobile
  • Manufacturer
  • Model
  • Network Type
  1. Laptop
  • Manufacturer
  • Model
  • CPU
  • GPU
  1. Mobile Accessories
    3.1 Charger
  • Manufacturer
  • Model
  • Charging Speed
    3.2 Cover
  • Manufacturer
  • Model
  • Is Rugged
    3.3 Other
  • Name
  • Manufacturer
  • Model
  • Additional Information (text)
  1. Other
  • Name
  • Manufacturer
  • Model
  • Additional Information (text)

I was thinking of using discriminators, but having a hard time with the mobile accessories having subtypes

Hey @Abdi_Mussa,

Welcome to the MongoDB Community Forums! :leaves:

A general rule of thumb while doing schema design in MongoDB is that you should design your database in a way that the most common queries can be satisfied by querying a single collection, even when this means that you will have some redundancy in your database. Thus, it may be beneficial to work from the required queries first, making it as simple as possible, and let the schema design follow the query pattern.

Using discriminators (as you mentioned) and embedding/referencing techniques would be a good approach. You can also use mgeneratejs to create sample documents quickly in any number, so the design can be tested easily.

Regarding mobile accessories having different subtypes like Chargers, Covers, and Others, one approach can be to create separate schemas for each subtype and embed them within the MobileAccessoriesSchema, ie, something like this:

const MobileAccessoriesSchema = new mongoose.Schema({
  type: String,
  manufacturer: String,
  model: String,
  // Other fields specific to Mobile Accessories
}, { discriminatorKey: 'accessoryType' });

const ChargerSchema = new mongoose.Schema({
  chargingSpeed: String,
});

const CoverSchema = new mongoose.Schema({
  color: String,
});

const OtherAccessorySchema = new mongoose.Schema({
  // Additional fields specific to Other Mobile Accessories
});

// Embed the subtype schemas within the MobileAccessoriesSchema
MobileAccessoriesSchema.add({
  charger: ChargerSchema,
  cover: CoverSchema,
  otherAccessory: OtherAccessorySchema,
});

// Create a mobile accessory of type Charger
const chargerAccessory = new MobileAccessories({
  name: 'Mobile Accessory',
  manufacturer: 'Manufacturer 2',
  model: 'Model 2',
  accessoryType: 'Charger',
  charger: {
    chargingSpeed: 'Fast',
  },
});
chargerAccessory.save();

Please note that this is just a suggestion and that the actual schema should depend on your queries, hence I would suggest you work on your queries as I stated above.

Hope this helps. Feel free to reach out for anything else as well.

Regards,
Satyam

If I embed each accessories in MobileAccessories as you suggested, how can I anticipate what the user is searching for? Like for example if he wants to search for both a Samsung charger and cover, how can I write a general search query that will execute any search queries?

Hey @Abdi_Mussa,

You can use a query like this to search for both a Samsung Charger and cover:

const samsungChargerAndCover = await MobileAccessories.find({
  $and: [
    {
      manufacturer: 'Samsung',
      accessoryType: { $in: ['Charger', 'Cover'] },
    },
  ],
});

Also, do note, that if the use of discriminators is making things complex, you can always choose to create different collections for different Mobile Accessories. I would start by thinking about the kind of queries that will be used most often and then start to model my data.

Regards,
Satyam

This query doesn’t work for other searches, as it is not general. What if one wanted to search for both mobile and mobile accessory with manufacturer ‘Samsung’? I wanted to have something as such in the query:
{ type:{$in:[typesFromSearch]} }
which would work as a general query.