Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define varying attributes for a product system in mongoose (node.js)

I’m building a personal shop app where users can sell items to each other, but I’m having a difficult time figuring out how to manage the products. For instance if you want to sell a t-shirt you should be able to pick a size and color etc. but if you sell a computer you should specify the year, cpu power etc. All products have a title, price, images and so on, but how would you get by with the varying attributes? I am using mongodb for the objects.

I was thinking about having a field attributes which should be an object with the different details, and then a have field type that would define which properties that exists. If type = 'Computer then I would know that attributes would look something like this.

attributes: { 
    capacity: 1000 // gb
    ram: 4096 // MB  
}

etc.

In a normal object oriented design I would have done this through inheritance / interfaces. If you have any idea on the best approach for this in mongoose / node.js I would be happy to hear about it.

If I'm not making myself clear in the question please tell me what is vague and what should be clarified

Edit:

The following article describes one solution to the problem http://learnmongodbthehardway.com/schema/chapter8/

It however doesn't state where to put the attributes. One solution might be to just store it in the category itself, but I'm not sure about best practices here though.

like image 945
chrs Avatar asked Nov 13 '15 14:11

chrs


1 Answers

An easy way to add inheritance to your Mongoose Schemas is to use Discriminators. This will allow you to create a parent Schema that can store attributes that are across all your products such as title, price, and images. You can then create child Schemas that will contain attributes specific to a product type such as Electronics and Clothing. For example in the Electronics Schema you can add attributes for cpu and ram that will not be present in the Clothing Schema.

Here is a basic example of how I set this up using Node and Mongoose.

Node/Javascript

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

// When you create a Electronic Product, it will set the type to Eletronic. 
var options = { discriminatorKey: 'type' };

// parent Product schema.
var productSchema = new mongoose.Schema({ name: String, price: Number }, options);
var Product = mongoose.model('Product', productSchema);

// child Electronic schema.
var ElectronicProduct = Product.discriminator('Electronic', new mongoose.Schema({ cpu: Number }, options));
var computer = new ElectronicProduct({ name: 'computer', price: 100, cpu: 5 });
computer.save();

// child Clothing schema. 
var ClothingProduct = Product.discriminator('Clothing', new mongoose.Schema({ size: String }, options));
var shirt = new ClothingProduct({ name: 'shirt', price: 50, size: 'Small' });
shirt.save();

If you log the objects that are saved they should look like

{ _id: 564b55983e5eec1ce2a44038,
  type: 'Electronic',
  cpu: 5,
  price: 100,
  name: 'computer' }
{ _id: 564b55983e5eec1ce2a44039,
  type: 'Clothing',
  size: 'Small',
  price: 50,
  name: 'shirt' }

When you attempt to access attributes that are not in the Product schema, it would be good practice to check if the attribute exists before trying to access it.

like image 67
jjbskir Avatar answered Oct 05 '22 13:10

jjbskir