DEV Community 👩‍💻👨‍💻

Muhammad Sifat Hossain
Muhammad Sifat Hossain

Posted on

Techland - an e-commerce app

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

Techland

Preview

Homepage

The homepage consists of featured categories and products.

Homepage

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.

Products Page

Individual Product Page

Clicking on a product takes you to the single product page to show details and related products

Product Description

Search Bar

Clicking the search bar opens a search modal. It can provide real-time auto completions.

Search Modal

Here we can select a suggestion or press Enter to see the full results.

Link to Source Code

Backend

Frontend

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;
}
Enter fullscreen mode Exit fullscreen mode

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>>;
}
Enter fullscreen mode Exit fullscreen mode

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"
          ]
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Finding Products by categoryId.

This on was a bit difficult, because categories are hierarchical. Example:

  1. Components
    1. MOBO
    2. CPU
    3. RAM
  2. Accessories
    1. Keyboard
    2. Mouse
    3. 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

  1. Node.js
  2. Express
  3. MongoDb

Frontend

  1. 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)

Welcome! 👋 Haven't Posted on DEV Yet?

Head over to our Welcome Thread and tell us a bit about yourself!