Replies: 7 comments 7 replies
-
Would it make sense to add a Creating a new sub-category would be pretty simple: ancestor_path = [parentCatg.ancestor_path, parentCatg.id].join(".") There would be some more work when moving a category as that would require: movedCatg.ancestor_path = [newParentCatg.ancestor_path, newParentCatg.id].join(".")
for (const childCatg of movedCatg.children) {
// recursively update child catg
} |
Beta Was this translation helpful? Give feedback.
-
I know this would complicate things a bit, but I can see quite common use cases for categories with multiple parents:
If not having multiple parents on categories, another option would be multiple categories per product. Although it would require more work from the user to manually add extra category to many products (could be automated). This option would also result in multiple categories with the same name, making it more difficult to differentiate them without seeing it's parent name. I do recognize the added complexity though. We would then create a directed acyclic graph instead of a tree structure, which would require some extra validations to make sure the graph stays acyclic (and not circular). |
Beta Was this translation helpful? Give feedback.
-
Hello Riqwan, Amazing job, just to clarify. Why cant we just remove the idea to add a relationship between categories? i mean, men and women has shoes, so we have 3 different categories shoes, women and men. When we apply filters, we can just select category men and shoes! On my point of view we can have a table of categories with a deep level, for example men and women could be level 1, clothing and accesories level 2, and rings or shoes level 3 With this type is structure we dont have redundant categories! Also, when we create a product we can choose in a select the categories we want for an item (ex: level 1 category men, level 2 category clothing, level 3 category shoes) Thank you for read me. Juanma Díaz. |
Beta Was this translation helpful? Give feedback.
-
Hi Riqwan, I am proposing a System default category. When the Category or Sub-Category is deleted - the items (or children) in that list can be auto-assigned to a system default category, which will not be visible to users. This will ensure that the data added in the wrong category/sub-category can be easily added again to the right category/sub-category with little effort by editing the items. There are chances that the category needs to be corrected; in that scenario, deleting the items and adding them again to the right category will take a lot of effort - if we provide a simple means to modify would make life easier for the person who maintains data. Does it make sense to you? Thanks, |
Beta Was this translation helpful? Give feedback.
-
Your talk about product categories in that RFC but what about the ability to add a single product to multiple collections? Like you said |
Beta Was this translation helpful? Give feedback.
-
Hello @riqwan, I ran into an issue - when I try to set the same parent to multiple categories I get this error |
Beta Was this translation helpful? Give feedback.
-
I wrote a feature request in this comment #2844 (reply in thread) "For example, say we have this category subtree: ?depth=0&q=perfume , would return [perfume] And you replied "can you share some use-cases on why you'd want to search for a category under a certain depth? I haven't seen many examples of categories being text-searched on an ecommerce store." and I said I didnt remember. Now I had to workaround this limitation, so let me tell you what the use-case is. Use caseI have 500 categories, with a depth of 8. I.e. with this feature added I don't need to load all 500 categories for main menu. It would also be useful to be able to get all categories, starting from a category id i.e. get all child categories starting from a category id. |
Beta Was this translation helpful? Give feedback.
-
Abstract
Providing a way for store managers to organise products into different categories that make it easier for users to browse through and find products that they are interested in.
Note: This RFC focuses purely on Categories and its nested capabilities. Adding products to a category will come in as a follow up RFC.
Motivation
Nested Categories are a way of organising products into a hierarchy of categories, with each level representing a more specific subcategory within the larger category. This makes it easier for customers to find the products they're looking for, as they can navigate through the categories to find the specific products they're interested in.
Collections, on the other hand, are groups of products that are being sold together for a limited time, such as a spring collection. While categories are mainly used for organising products, collections are more focused on grouping products for sales or marketing purposes.
Goals
Non Goals
Proposal
From the list of tree depictions possible in relational databases (nested set, materialised paths, closure tables), I’m proposing the fairly simple and straightforward “Parent-Child” structure for the following reasons:
This is a simple visual of how the category parent-children relationship look like:
Each category node, contains the
ID
of its parent category node.Limiting the tree depth
To build out the entire tree, we do have to recursively call each child until the last node or vice versa for the parent node. This can very quickly cause O(N²) performance issues when we have a very deep tree structure. To contain this, we should have a limit on the nested depth. By default we could recommend a limit of 4, but this can be configurable if customers are willing to make the performance tradeoff. Lets refer to this as
MAX_CATEGORY_DEPTH
from here onwards.I've taken a look at some large ecommerce sites and can see that they don't go beyond 4 category levels.
Taking a deeper dive into this diagram, lets split our operations that we can perform on a category.
Adding a new Category
parent_id
asnull
MAX_CATEGORY_DEPTH
parentCategory
parent_id
asparentCategory.id
Moving a category
parent_id
asnull
newParentCategory
newParentCategory.id
(”catg_03”)Note: The caveat here is that the subtree of this category will tag along the journey as well
Deleting a category
Note: This will have implications on product categories, but we are not going to focus on that aspect here. This will come in as a separate RFC.
Fetching collection of categories
Every category fetch in a collection, makes 2 additional DB queries and returns this in the response:
You can fetch categories with a few filters:
With this, the number of API calls to build an entire tree path will be
MAX_CATEGORY_DEPTH - 1
Fetching a category
Every category fetch (GET /categories/:id), makes a few additional DB queries and returns this in the response:
Note: These can be optimized to use a single query using recursive search
Caching
Categories API call will be a dominant API call used by almost all customer that enters the store front. The cost of querying even with the limitations we’ve applied for it is still fairly high. Luckily, categories are something that don’t change too often. We can heavily rely on caching to take care of the bulk of the work and purge cache whenever operations on categories are performed.
We can introduce a service level cache to prevent queries from hitting the db as much.
Model Layer
Beta Was this translation helpful? Give feedback.
All reactions