首先,让我明确一点,我不要求任何代码;我只是不想对如何实现我将要问的问题提出一些一般的想法/指导/意见。
我开始构建一个在线电子商务系统(Yii2 + MongoDB,所以,PHP + NoSQL),有两个条件我不完全确定如何在不在我的代码和数据库中造成巨大混乱的情况下实现。
这两个条件是相关的,所以我将它们解释为一个。
与任何其他严肃的电子商务一样,它将有类别。而且,与任何其他严肃的电子商务一样,每种产品都会有 tags
或options
.让我进一步解释一下我所说的tags
/options
。
这些是用户在购买产品时可以选择的可用选项,例如颜色或尺寸、材料等。
- 类别
将有多个general
类别以及其他子类别。例如,Electronics
可以是一般类别,子类别可以是Computers
和Smart TVs
。然后,Motherboards
和RAM
可能是Computers
的子类别。
这本身可以很容易地存储在数据库中,但问题就在这里了:
- 每个产品都应在列出其所属的任何类别或较高类别时显示。这意味着,如果我(作为最终用户)浏览
Computers
类别中的所有项目,我应该看到属于类别Computers
子类别Graphic cards
NVIDIA GTX670
。
我可以通过以下方式保存每个产品:
{
_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
可以具有选项size
和color
,但类别Sunglasses
(Woman fashion
的子类别)只能有 color
个,甚至是另一组选项,与Woman fashion
完全不同。
此外,每个选项中的值(red
、green
、blue
color
选项中的值)可以随机出现在随机类别中。所以Woman fashion
会有像Strawberry Red
和Tangerine
这样的颜色,而Cars
会有Carbon
和Black metallic
。
此外,还有几种类型的选项:
- 完全静态(如
size
,只能是S
或M
,但不能两者兼而有之。在任何情况下,管理员都无法编写自定义大小,例如Kind of small
;他将能够选择数据库中已有的内容)。 - 可以组合在一起的静态(如
colors
,可以是red
或green
,也可以是管理员选择的颜色组合)。 - 自由输入(如
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
]
}
但我担心当有 30 个类别并且选项的每个值都设置为出现在随机类别中时,单个选项会变成多大.
我也只是看得不够干净,但也许那只是我。
无论如何,与上一点一样,请随时提出任何可以提出的建议,我将非常感谢您能给我的任何反馈。
我也在经营一个电子商务网站。这是我关于如何实现您提到的功能的建议。希望对您有所帮助。
- 类别
我将它们组织在一个扁平的结构中,在您的情况下,它将是:
{_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
索引在这里有效,所以它会很快。 当您找到所有子类别时,您可以轻松找到其中的所有产品(在Product
集合的categoryIds
上构建索引)。
或者,您可以将所有类别读入内存,并使用键>categoryId,值>[所有子类别]构建哈希表。您的类别通常不会经常更改,也不会有很多类别。这样就没事了。
- 标签/选项
首先,我认为你的类别有问题。 Women fashion
是通用的,你应该把你的产品放到更具体的东西里,选项也应该在那里。例如,可能有一个类别coat
具有size
和color
,而不是women fashion
。虽然women fashion
中可能仍然有color
选项,因为它是所有子类别的共同特征。
如果您考虑一下,为什么所有子类别都组织在一个父类别中?因为他们有一些共同点。该公共部分应该是父类别的通用选项。也就是说,所有父类别和子类别之间应该有一个继承。例如:
女士时尚:色彩
|-外套: 大小
|-太阳镜:形状
然后coat
最终将有 2 个选项color
和size
。 sun glasses
: color
& shape
.当您查看women fashion
时,只有 1 个选项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
因此,当您获得 1GB 和 1TB 的硬盘时,您可能需要在过滤产品之前进行转换。这是题外话,我会回到你的问题。
请注意,尽管不同类别的选项具有相同的名称。它们不太可能是一回事。 Coat
和Furniture
Material
是两回事。所以我倾向于为不同的类别定义不同的选项。因此,toys
可能有color
,women fashion
color
。这与上面提到的继承并不冲突,因为从某种级别来看,子类别开始共享相同的选项。这完全与你如何组织类别结构有关。如果你想改变类别结构或移动产品一段时间,那将是痛苦的。因此,在定义类别时要小心。
这就是我脑海中浮现的全部内容。恐怕我的母语不是英语,因此您可能会发现我的答案的某些部分难以理解。请随时告诉我。