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

时间:2015-02-02 00:10:52

标签: php mongodb yii2 nosql

首先,让我明确表示我不会要求任何代码;我只是想知道如何实现我要问的内容。

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

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

与任何其他严肃的电子商务一样,它也会有类别。此外,与任何其他严肃的电子商务一样,每种产品都有tagsoptions。让我再解释一下我称之为tags / options的内容。

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

  1. 分类
  2. 会有多个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
        ]
    }
    

    可是:

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


    2. 标签/选项

    这是真正头痛的地方。

    每个选项可能属于0个或更多类别和子类别,因此类别Woman fashion可以包含选项sizecolor,但类别Sunglasses(子类别) Woman fashion)可能只有color,甚至是另一组选项,与Woman fashion完全不同。

    此外,red选项中每个选项(greenbluecolor)内的值可能会出现在随机类别中。因此Woman fashion会有Strawberry RedTangerine之类的颜色,而Cars会有CarbonBlack metallic

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

    • 完全静态(例如size,可能只有SM,但从不两者兼而有之。无论如何,管理员将无法编写自定义大小,如Kind of small;他可以只选择数据库中已有的内容。
    • 可以组合在一起的静态(例如colors,可以是redgreen,也可以是管理员选择的颜色组合。
    • 免费输入(例如dimensionsweight,理想情况下是要加入的输入字段和下拉值。例如[10] | (mg||kg|tons)或{ {1}} [20])。


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

    (cm|m|km|miles)

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

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

1 个答案:

答案 0 :(得分: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/", ...}

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

    {
        _id: asdasfwetrw34tw34t245y45y,
        name: "NVIDIA GTX670",
        price: 99.50,
        ...
        ...
        categoryIds: [3]
    }

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

    db.categories.find({idPath: /^\/0\/1/})

idPath索引在这里工作,所以它会很快。当您找到所有子类别时,您可以轻松找到其中的所有产品(在categoryIds集合的Product上构建索引。)

或者,您可以将所有类别读入内存并使用key-&gt; categoryId,value-&gt; [所有子类别]构建哈希表。您的类别通常不会经常更改,您将不会有很多类别。因此它会没事的。

  • 标签/选项

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

  女性时尚:颜色
  | - 涂层:尺寸
  | - 太阳镜:形状

然后color最终会有两个选项size&amp; sun glassescolorshape&amp; women fashion。当您查看color时,只有一个选项women fashion。它也会过滤子类别,因为它们继承自Strawberry Red 至于颜色的值,我的想法只使用标准颜色red实际上是Tangerineorange实际上是color。过滤产品时,您并不希望它们出现。否则会有太多选择,绝对不利于用户体验 但是,除了类别中的customizable options选项外,我的网站还有一些名为Strawberry Red的内容。这些选项仅在产品上定义。当您查看类别时,它们永远不会出现在这里你可以Tangerine&amp; Tangerine with figure。在我看来,这些不是产品的“天然”特性。它们仅用于使用户在查看产品时感觉更舒适。因此,你也可以选择color等类似的选项 选项还有一件事。您可能想要标记哪些选项应该用于过滤产品。例如dimension肯定是一个。虽然Number可能不是。

关于选项类型。如果它对你来说足够了你的。我有更多类型,例如StringSingle ChoiceMultiple ChoicesUnit。我还计划实施Unit1GB = 1024MB = 1024*1024B 的棘手部分就是例如

Material

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

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

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