如何在mongoose(node.js)中定义产品系统的不同属性

时间:2015-11-13 14:43:07

标签: javascript node.js mongodb orm mongoose

我正在构建一个个人商店应用程序,用户可以相互销售商品,但我很难搞清楚如何管理产品。例如,如果你想卖T恤,你应该能够选择尺寸和颜色等,但如果你卖电脑,你应该指定年份,CPU功率等。所有产品都有标题,价格,图像等在,但你会如何与不同的属性相处?我正在使用mongodb作为对象。

我在想一个字段attributes,它应该是一个具有不同细节的对象,然后是一个字段type,用于定义存在哪些属性。如果type = 'Computer那么我会知道attributes看起来像这样。

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

在正常的面向对象设计中,我会通过继承/接口完成此操作。如果您对mongoose / node.js中的最佳方法有任何想法,我会很高兴听到它。

如果我没有在问题中表明自己,请告诉我什么是模糊的,应该澄清什么

编辑:

以下文章介绍了该问题的一种解决方案 http://learnmongodbthehardway.com/schema/chapter8/

然而,它并没有说明放置属性的位置。一种解决方案可能只是将其存储在类别中,但我不确定这里的最佳实践。

3 个答案:

答案 0 :(得分:8)

向Mongoose Schema添加继承的简单方法是使用Discriminators。这将允许您创建父架构,该架构可以存储所有产品中的属性,例如标题,价格和图像。然后,您可以创建包含特定于产品类型(如电子和服装)的属性的子架构。例如,在电子模式中,您可以添加服装模式中不存在的cpu和ram的属性。

以下是我如何使用Node和Mongoose进行设置的基本示例。

<强>节点/使用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();

如果您记录保存的对象,它们应该是

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

当您尝试访问不在Product架构中的属性时,最好在尝试访问该属性之前检查该属性是否存在。

答案 1 :(得分:3)

如果你问的是如何处理模式我会说你的模型属性是一个对象数组或混合类型

http://mongoosejs.com/docs/schematypes.html

因为你可以为属性提供许多可能的选项,所以不可能事先知道所有这些选项。也许您希望用户定义属性的名称(键)和值。然后,一旦获得对象,就可以使用for in循环将密钥用作标签和值。

示例:

var attributes = [];

for ( attr in item.attributes ) {
    //do something with the key=>value pair
    attributes.push({
        label: attr,
        value: item.attributes[attr]
    }); 
}

//iterate through the new array to display your item attributes

答案 2 :(得分:1)

对于这种动态数据场景,我更希望将属性保存为 Mongoose Model 中的空对象,以便您可以为每个文档使用不同的属性。

<强>模型

public static String getCurrentTimeStamp() {
    SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date now = new Date();
    String strDate = sdfDate.format(now);
    return strDate;
} 

您可以使用attributes对象指定特定产品的不同属性。

<强>控制器

var mongoose = require('mongoose');
Schema = mongoose.Schema;

var productSchema = new mongoose.Schema({
    title:{type:String,required}, // Common Attributes
    price:{type:Number,required}, // Common Attributes
    images:[buffer], // Common Attributes
    //Other Common Attributes goes here
    attributes:{} // Empty attributes object which can vary for each product.
});

var Product = mongoose.model('Product', productSchema);

<强>参考

http://mongoosejs.com/docs/schematypes.html(查找混合数据类型)

注意

还有其他方法可以创建此模式,一种方法是将属性作为包含所有属性组合的嵌入文档,如果不适用,可以将值保持为null。

希望这有帮助。