Прежде всего, позвольте мне пояснить, что я не прошу какого-либо кода; Я просто не знаю общих идей / рекомендаций / мнений о том, как я могу реализовать то, что я собираюсь спросить.
Я начинаю строить онлайн-систему электронной коммерции (Yii2 + MongoDB, так что PHP + NoSQL), и есть два реквизита, которые я не совсем уверен, как реализовать, не создавая огромного беспорядка как в моем коде, так и в база данных.
Оба реквизита связаны, поэтому я объясню их как один.
Как и любая другая серьезная электронная коммерция, у нее были бы категории. А также, как и любая другая серьезная электронная коммерция, каждый продукт будет иметь tags
или options
. Позвольте мне немного пояснить, что я называю tags
/ options
.
Это доступные параметры, которые пользователь мог выбрать при покупке продукта, например, цвет или размер, материал и т. Д.
Было бы несколько general
категорий, а также других подкатегорий. Например, Electronics
может быть общей категорией, а подкатегориями будут Computers
и Smart TVs
. Тогда Motherboards
и RAM
могут быть подкатегориями « 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
категории « 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
работает индекс idPath
поэтому он будет быстрым. когда вы узнаете обо всех подкатегориях, вы можете легко найти все продукты в них (создать индекс в categoryIds
о Product
).
Или, альтернативно, вы можете прочитать все категории в памяти и построить хеш-таблицу с ключ-> categoryId, value -> [все подкатегории]. Обычно ваши категории не будут меняться часто, и у вас не будет много категорий. Таким образом, все будет хорошо.
Прежде всего, я думаю, что с вашей категорией что-то не так. Women fashion
– это нечто общее, вы должны поместить свой продукт в нечто более конкретное, и варианты должны быть там тоже. Например, может быть, категория coat
которое имеет size
и color
, кроме women fashion
. Хотя у women fashion
все еще может быть color
потому что это обычная характеристика для всех подкатегорий.
Если вы думаете об этом, почему все подкатегории организованы в одну родительскую категорию? потому что у них есть что-то общее. Эта общая часть должна быть общими вариантами родительской категории. то есть должно быть наследование между всеми родительскими категориями и подкатегориями. Например:
женская мода: цветная
| -слойный: размер
| -sun очки: форма
Тогда 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
Поэтому, когда вы получаете жесткий диск объемом 1 ГБ и 1 ТБ, вы можете сделать преобразование перед фильтрацией продуктов. Это не в тему, я вернусь к вашему вопросу.
Обратите внимание, что, хотя параметры разных категорий имеют одинаковое имя. Они вряд ли совпадают. Material
Coat
и Furniture
– это две разные вещи. Поэтому я склонен определять разные варианты для разных категорий. Таким образом, может быть, color
для toys
и color
для women fashion
. Это не противоречит упомянутому выше наследованию, поскольку с некоторого уровня подкатегории начинают использовать одни и те же параметры. Это полностью связано с тем, как вы упорядочиваете свою структуру категорий. И если вы хотите изменить структуру категории или переместить продукты некоторое время, это будет болезненно. Поэтому будьте осторожны, когда вы определяете свои категории.
Это все, что приходит мне в голову. Боюсь, что я не носитель английского языка, поэтому вы можете найти часть моего ответа, которую трудно понять. Не стесняйтесь, дайте мне знать.