← Go Back

Building Ai Search Product

Sep 29, 2025 2min
#golang #mysql

This is a simple project I’ve wanted to build for a long time. The idea is to create a backend API service that stores products with information such as name, price, and manual in a structured database. Beyond basic CRUD operations, the API will support searching for specific information using vector search and leverage AI capabilities to generate proper, human-like responses.

 

First things first—when I came back to the project, I didn’t know how to run migrations.
 So what I did was use the SQL query: 

CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    manual_link TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);


Then I started creating products from Postman.
 I think I’ll eventually need to make a seeder for that, but what I was thinking is that I should first create the table when the code runs for the first time.
 
I already have this simple function:
 

func ConnectDB() *sql.DB {
    dsn := "root@tcp(127.0.0.1:3306)/expirment_ai_search_products?parseTime=true"
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal("Failed to open DB:", err)
    }

    if err := db.Ping(); err != nil {
        log.Fatal("Failed to connect to DB:", err)
    }

    DB = db
    return db
}


I’ll use the returned db to execute the SQL query to create the products table, using this function:
 

func CreateProductTable(db *sql.DB) {
    query := `
    CREATE TABLE IF NOT EXISTS products (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        price DECIMAL(10,2) NOT NULL,
        manual_link TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    `

    _, err := db.Exec(query)
    if err != nil {
        log.Fatalf("Failed to create products table: %v", err)
    }

    log.Println("✅ Products table created or already exists.")
}


With that done, I also added a little function to insert some dummy test data (and for the record, don’t ask about the manuals 😂):
 

func InsertProductRecord(db *sql.DB) {
    query := `
    INSERT INTO products (name, price, manual_link) VALUES
      ('Laptop X200', 1299.99, 'https://example.com/manuals/laptop-x200.pdf'),
      ('Smartphone Pro', 899.50, 'https://example.com/manuals/smartphone-pro.pdf'),
      ('Wireless Headphones', 199.90, 'https://example.com/manuals/headphones.pdf'),
      ('Gaming Monitor', 449.00, 'https://example.com/manuals/monitor.pdf'),
      ('Mechanical Keyboard', 120.75, 'https://example.com/manuals/keyboard.pdf');
    `

    _, err := db.Exec(query)
    if err != nil {
        log.Fatalf("Failed to insert dummy data: %v", err)
    }

    log.Println("✅ Dummy product records inserted.")
}


Since I already have an API endpoint that replaces the manual for each product (/products/upload/:product_id), the request body just contains the manual file path.
 
But the real question is: where do I get those manuals? One simple idea is to generate PDFs as dummy data for each product, but that wouldn’t be a great test case.
 
So my next step will be to build a tool in Go that generates dummy manual data and downloads them automatically.