What I built
Techland is an online e-commerce store where users can list, search and buy computer components.
Category Submission: Search No More
App Link
Preview
Homepage
The homepage consists of featured categories and products.
Products Page
Clicking on a category or the Products link on the navigation bar takes you to the products page. It shows all the products or specific products from a selected category and its sub-categories.
Individual Product Page
Clicking on a product takes you to the single product page to show details and related products
Search Bar
Clicking the search bar opens a search modal. It can provide real-time auto completions.
Here we can select a suggestion or press Enter to see the full results.
Link to Source Code
Permissive License: MIT
Background
Honestly, this is my first full-stack application and it doesn't do anything extra-ordinary. I've always wanted to build one (for my portfolio) and have been taking few courses on Mongodb University. Finally this hacakthon gave me a the right opportunity to challenge myself and here I'm writing this post at 4:40am in the morning.
How I built it
This whole app is centered around searching, filtering and fetching product data from the database in the most convenient form. So before we start we need to know about the shape of our products and its category.
Product Category Interface
interface CategoryInterface {
_id: string;
hash: string;
name: string;
createdAt: number;
isDeleted: boolean;
imageId: string | null;
parentId: string | null;
description: string | null;
}
Product Interface
interface ProductImage {
id: string;
isMain: boolean;
}
interface ProductBrand {
id: string;
name: string;
}
interface CommonProductFields {
_id: string;
name: string;
price: number;
createdAt: number;
priceUnit: string;
categoryId: string;
brand: ProductBrand;
description: string;
images: ProductImage[];
lastModifiedAt: number;
shortDescriptions: string[];
specifications: Record<string, Record<string, string>>;
}
Full-text search
For full text search I'm using the name
, brand.name
, shortDescriptins
and description
fields. At first, I was a bit worried about the description
field, because it contains HTML. But, luckily after reading a lot of documentation I found that I can create a custom text analyzer to strip out all the html before indexing.
Auto-completion
For auto-completion I'm only using only the name
field.
Similar Products
I actually didn't know that MongodBD can do this. But I found a search stage called moreLikeThis
that can compare text based on search index. So, guess what? I've implemented finding similar products without using fancy AI. For this query I've used the categoryId
and specifications
field to find similar items.
Here is my atlas search index:
{
"mappings": {
"dynamic": false,
"fields": {
"brand.name": { "type": "string", "analyzer": "lucene.keyword" },
"categoryId": { "type": "string", "analyzer": "lucene.keyword" },
"name": [
{
"type": "autocomplete",
"foldDiacritics": false,
"tokenization": "edgeGram",
"analyzer": "lucene.standard"
},
{ "type": "string", "analyzer": "lucene.standard" }
],
"description": {
"type": "string",
"analyzer": "productDescriptionAnalyzer"
},
"shortDescriptions": { "type": "string", "analyzer": "lucene.standard" },
"specifications": { "dynamic": true, "type": "document" }
}
},
"analyzers": [
{
"name": "productDescriptionAnalyzer",
"charFilters": [{ "type": "htmlStrip" }],
"tokenizer": { "type": "standard" },
"tokenFilters": [
{ "type": "lowercase" },
{ "type": "snowballStemming", "stemmerName": "english" },
{
"type": "stopword",
"tokens": [
"a",
"i",
"am",
"an",
"as",
"at",
"be",
"by",
"do",
"he",
"if",
"in",
"is",
"it",
"me",
"no",
"of",
"on",
"or",
"so",
"to",
"up",
"we",
"all",
"and",
"are",
"for",
"has",
"her",
"his",
"off",
"our",
"out",
"the",
"you",
"over",
"that",
"this",
"with",
"your",
"other"
]
}
]
}
]
}
Finding Products by categoryId
.
This on was a bit difficult, because categories are hierarchical. Example:
- Components
- MOBO
- CPU
- RAM
- Accessories
- Keyboard
- Mouse
- Headphone
So, if I'm listing products form the Components category then I should also list all products from its sub-categories. Glad, the $graphLookup
stage solved the problem.
There is so much that I want to describe but sadly, I don't have much time left. I wanted to make a video explanation but can't do it right now.
I'll try to add some documentation in the docs
folder of my backend app.
Tech-stack
Backend
- Node.js
- Express
- MongoDb
Frontend
- React
Conclusion
Lastly, I want to say thanks to the MongodDb team for organizing this beautiful event. I'm especially grateful for the free courses provided by the MongoDb University. I've learned almost everything I know about Mongodb from those courses. Thank you for reading the post π.
Top comments (0)