保存,组织和查询产品,选项/标签和类别

ale*_*nst 4 php mongodb nosql yii2

首先,让我明确表示我不会要求任何代码; 我只是想要一些关于如何实现我要问的内容的一般性想法/指导/意见.

我开始建立一个在线电子商务系统(Yii2 + MongoDB,所以,PHP + NoSQL),有两个必要条件,我不完全确定如何实现,而不会在我的代码和数据库.

两个必需品都是相关的,所以我将它们解释为一个.

与任何其他严肃的电子商务一样,它也有类别.而且,与任何其他严肃的电子商务一样,每种产品都会有tagsoptions.让我再解释一下我所说的tags/ options.

这些是用户在购买产品时可以选择的可用选项,例如颜色或尺寸,材料等.

  1. 分类

将有多个general类别以及其他子类别.例如,Electronics可以是一般类别,子类别可以是ComputersSmart TVs.然后,MotherboardsRAM可能的子类Computers.

这本身可以很容易地存储在数据库中,但是这里出现问题:

  • 列出其所属的任何类别或上层类别时,应显示每个产品.这意味着如果我(作为最终用户)浏览Computers类别中的所有项目,我应该看到NVIDIA GTX670哪个属于该类别的子Graphic cards类别Computers.

我可以通过以下方式保存每个产品:

{
    _id: asdasfwetrw34tw34t245y45y,
    name: "NVIDIA GTX670",
    price: 99.50,
    ...
    ...
    categories: [
        "Electronics", //<-- just the ID of that group
        "Computers", //<-- just the ID of that group
        "Graphic cards" //<-- just the ID of that group
    ]
}
Run Code Online (Sandbox Code Playgroud)

但:

  • 我不确定检索某个类别的所有项目(当然还有所有子类别的项目)的查询速度有多快.
  • 我不确定该方法有什么其他缺点,所以,请随意推荐任何替代架构来存储它.


2. 标签/选项

这是真正头痛的地方.

每个选项可能属于0或多个类别和子类别,使类别Woman fashion可以有选择sizecolor,但类别 Sunglasses(子类别Woman fashion)只能有color,甚至是另一套方案,从完全不同的Woman fashion.

此外,每个选项里面的值(red,green,bluecolor选项)可能出现在随机的类别.所以Woman fashion会有颜色Strawberry RedTangerine,虽然Cars会有CarbonBlack metallic.

此外,还有几种类型的选择:

  • 完全静态(例如size,可能只是S或者M,但绝不是两者.在任何情况下,管理员都无法编写自定义大小,例如Kind of small;他可以只选择它已经在数据库中的内容).
  • 静态可以结合在一起(例如colors,其可以是redgreen,或者管理员选择的颜色的组合).
  • 自由输入(dimensions或者weight,理想情况下,可以是要加入的输入字段和下拉值.例如[10]| (mg||kg|tons)[20] (cm|m|km|miles)).


我可以像这样保存每个选项:

{
    option: "Color",
    type: "Static with combinations"
    values: [
        {
            value: "Red",
            categories: [
                "Sunglasses"
            ]
        },
        {
            value: "Green",
            categories: [
                "Sunglasses",
                "T-Shirts"
            ]
        },
        {
            value: "Black metallic",
            categories: [
                "Cars"
            ]
        }
    ],
    categories: [
        "Woman fashion", //<-- only the ID of this group
        "Cars" //<-- only the ID of this group
    ]
}
Run Code Online (Sandbox Code Playgroud)

但是我担心单个选项有多大,当有30个类别时,该选项的每个值都设置为随机类别.
我也觉得它看起来不够干净,但也许这只是我.

无论如何,与前一点一样,请随时提出任何可以提出的建议,我将非常感谢您给我的任何反馈.

yao*_*ing 5

我也在运营一个电子商务网站.以下是我如何实现您提到的功能的建议.希望能帮助到你.

  • 分类

我把它们整理成一个扁平的结构,在你的情况下它将是:

    {_id: 1, name: "Electronics", parentId: 0, idPath: "/0/1/" ...}
    {_id: 2, name: "Computers", parentId: 1, idPath: "/0/1/2/", ...}
    {_id: 3, name: "Graphic Cards", parentId: 2, idPath: "/0/1/2/3/", ...}
Run Code Online (Sandbox Code Playgroud)

而产品现在只需要在叶子类别中.在你的情况下:

    {
        _id: asdasfwetrw34tw34t245y45y,
        name: "NVIDIA GTX670",
        price: 99.50,
        ...
        ...
        categoryIds: [3]
    }
Run Code Online (Sandbox Code Playgroud)

当然,产品可以分为多个类别,因此categoryIds仍然是一个阵列.这是棘手的部分.列出Electronics类别时,您可以通过以下方式找到其所有子类别:

    db.categories.find({idPath: /^\/0\/1/})
Run Code Online (Sandbox Code Playgroud)

idPath索引在这里工作所以它会很快.当你发现所有的子类,你可以很容易地找到他们所有的产品(建立在指数categoryIdsProduct集合).

或者,您可以将所有类别读入内存并使用key-> categoryId,value - > [所有子类别]构建哈希表.您的类别通常不会经常更改,您将不会有很多类别.因此它会好起来的.

  • 标签/选项

首先,我认为您的类别存在问题.Women fashion是通用的东西,你应该把你的产品放到更具体的东西,选项也应该在那里.例如,可能有一个类别coat,其中包含size&color,而不是women fashion.虽然可能仍有color选择,women fashion因为它是所有子类别的共同特征.
如果您考虑一下,为什么所有子类别都组织在一个父类别中?因为他们有共同点.这个共同部分应该是父类别的共同选项.也就是说,所有父类别和子类别之间应该存在继承.例如:

女性时尚:颜色
| - 外套:尺码
| - 太阳镜:外形

然后coat最终将有2个选项color&size.sun glasses:color&shape.在您查看时women fashion,只有一个选项color.它也会过滤子类别,因为它们继承自women fashion.
至于颜色的值,我的想法是只使用标准颜色Strawberry Red居然是red,Tangerine居然是orange.过滤产品时,您并不希望它们出现.否则会有太多的选择,绝对不利于用户体验.
但是,除了color该类别的选项外,我的网站还有一些名称customizable options.这些选项仅在产品上定义.当您查看类别时,它们永远不会出现 在这里你可以拥有Strawberry Red&Tangerine.在我看来,这些不是产品的"天然"特性.它们仅用于使用户在查看产品时感觉更舒适.因此,你也可以选择这种类型Tangerine with figure
选项.您可能想要标记哪些选项应该用于过滤产品.例如color肯定是一个.虽然dimension可能不是.

关于选项类型.如果它对你来说足够了你的.我有很多类型,如Number,String,Single Choice,Multiple Choices.我也计划实施Unit.Unit例如,棘手的一部分就是这样

1GB = 1024MB = 1024*1024B
Run Code Online (Sandbox Code Playgroud)

因此,当您获得1GB和1TB的硬盘时,您可能希望在过滤产品之前进行转换.这不是我将回到你的问题的主题.

请注意,虽然不同类别的选项具有相同的名称.他们不太可能是同一件事.MaterialCoatFurniture2个不同的东西.所以我倾向于为不同的类别定义不同的选项.因此,可能colortoys,colorwomen fashion.这与上面提到的继承没有冲突,因为从某种程度上说,子类别开始共享相同的选项.这与您组织类别结构的方式完全相关.如果你想改变类别结构或移动产品一段时间,那将是痛苦的.因此,在定义类别时要小心.

这就是我想到的一切.我担心我不是母语为英语的人,因此你可能会发现我的答案有些难以理解.请随时告诉我.