DEV Community

Cover image for From searching to solving: how Vector Databases transform product discovery
Roberto B.
Roberto B.

Posted on

From searching to solving: how Vector Databases transform product discovery

Today’s users expect more than a search bar.
Whether they’re shopping online, browsing a company’s product catalog, or looking for help on a support site, they no longer want to sift through endless results or guess the right keywords.

They expect intelligent systems that can understand them, their needs, their context, and even the way they describe their problems.

For example:

  • In an e-commerce store, a shopper might type "There's a lot of humidity in my room" instead of searching for "dehumidifier",
  • On a tech product site, someone could write "I need to recharge my phone on the go" rather than "portable power bank".
  • On a wellness platform, a visitor might say "I need something for my yoga classes" instead of "yoga mat".

In traditional keyword-based search, these queries would fail, but their meaning is clear.

The user is expressing an intent, not a term.

This shift is driving the rise of semantic search, powered by vector databases and embeddings — technologies that enable systems to understand what users mean, not just what they type.

The solution: turning product data into meaning

What if our system could understand what the user means, not just what they type?

By transforming product descriptions into vector representations, each product becomes a semantic entity, a numerical fingerprint of its meaning.

This allows us to:

  • Embed every product description into a vector space.
  • Embed the user’s query the same way.
  • Compare them using similarity search to find the most relevant product, even if no words match exactly.

For example:

User query: “My room has a lot of humidity.”

System response: “Compact dehumidifier for small rooms and closets.”

No keyword overlap, just pure semantic understanding.

The tech stack behind semantic search

To illustrate this concept, let’s build a hands-on example using:

  • LangChain (as our orchestration layer) to manage embeddings and similarity search.
  • Ollama (as our local AI model provider) to generate embeddings.
  • Bun (as our modern JS runtime) for fast, interactive execution.

We’ll use nomic-embed-text, an open model optimized for generating text embeddings.

The example: semantic product finder in JavaScript

Here’s a working demo that shows how to search by needs instead of keywords.

// semantic-search-bun.js

import { OllamaEmbeddings } from "@langchain/ollama";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
import { Document } from "@langchain/core/documents";

// --- Configuration ---
// Make sure Ollama is running locally and the model is available
// Example: ollama pull nomic-embed-text
const embeddings = new OllamaEmbeddings({
  model: "nomic-embed-text",
  baseUrl: "http://localhost:11434",
});

// --- Product catalog ---
const productDescriptions = [
  "Wireless Bluetooth headphones with noise cancellation and 30-hour battery life.",
  "Ergonomic office chair with lumbar support and breathable mesh fabric.",
  "4K Ultra HD Smart TV with HDR10 and built-in streaming apps.",
  "Compact espresso machine with milk frother and reusable filter basket.",
  "Water-resistant smartwatch with heart rate and sleep tracking features.",
  "Lightweight running shoes designed for comfort and performance.",
  "Portable power bank with 20000mAh capacity and fast charging ports.",
  "Adjustable standing desk with motorized height control and memory settings.",
  "Smart LED bulb compatible with Alexa and Google Home voice control.",
  "Noise-cancelling wireless earbuds with touch controls and charging case.",
  "Durable stainless steel cookware set with nonstick coating.",
  "Eco-friendly bamboo cutting board with juice groove and handle.",
  "Professional DSLR camera with 24MP sensor and Wi-Fi connectivity.",
  "Rechargeable electric toothbrush with multiple cleaning modes.",
  "Foldable drone with 4K camera and GPS-assisted flight.",
  "Compact Bluetooth speaker with deep bass and waterproof design.",
  "High-performance gaming mouse with customizable RGB lighting.",
  "Slim leather wallet with RFID blocking technology.",
  "Waterproof action camera with wide-angle lens and 1080p recording.",
  "Premium memory foam pillow for side and back sleepers.",
  "Cordless handheld vacuum cleaner with powerful suction and HEPA filter.",
  "Smart home security camera with motion detection and night vision.",
  "Stainless steel insulated travel mug with leak-proof lid.",
  "Wireless keyboard and mouse combo with ergonomic design.",
  "Fitness tracker with calorie counter and step monitor.",
  "Electric hair clipper set with adjustable blades and accessories.",
  "Lightweight laptop backpack with USB charging port.",
  "Non-stick air fryer with digital display and temperature control.",
  "Scented soy candle with lavender essential oils for relaxation.",
  "Portable mini projector with HDMI and Wi-Fi connectivity.",
  "Smart thermostat with mobile app control and energy-saving mode.",
  "Electric scooter with long-range battery and foldable design.",
  "Organic green tea with antioxidants and refreshing flavor.",
  "Luxury cotton bath towel set with soft absorbent texture.",
  "Wireless charging pad compatible with iPhone and Android devices.",
  "Pet grooming kit with quiet motor and precision trimming tools.",
  "LED desk lamp with adjustable brightness and touch control.",
  "Compact portable blender for smoothies and protein shakes.",
  "Wooden bookshelf with adjustable shelves and modern design.",
  "Stainless steel reusable water bottle with double insulation.",
  "Digital alarm clock with USB ports and dimmable display.",
  "Foldable camping chair with cup holder and carrying bag.",
  "Smartphone tripod with Bluetooth remote and flexible legs.",
  "Electric pressure cooker with multiple preset cooking programs.",
  "Soft microfiber bedsheet set with wrinkle-resistant finish.",
  "Solar-powered garden lights with automatic dusk-to-dawn sensor.",
  "Noise-reducing blackout curtains for bedroom or living room.",
  "Wireless car charger mount with automatic clamping feature.",
  "Compact dehumidifier for small rooms and closets.",
  "Adjustable yoga mat strap with eco-friendly non-slip mat.",
  "Stainless steel smartwatch band replacement for Apple Watch.",
];

const vectorStore = new MemoryVectorStore(embeddings);

// --- Load product embeddings ---
console.log("📦 Loading product catalog into vector memory...");
for (const productDescription of productDescriptions) {
  let document = new Document({
    pageContent: productDescription,
  });
  await vectorStore.addDocuments([document]);
  process.stdout.write(`✅`);
}
console.log(`✅ Loaded ${productDescriptions.length} products.`);

// --- Interactive prompt using Bun ---
const prompt = "\n🛒 What do you need? (type 'quit' to exit): ";
process.stdout.write(prompt);

for await (const line of console) {
  const query = line.trim();
  if (query.toLowerCase() === "quit") {
    console.log("👋 Goodbye!");
    break;
  }

  console.log("\n🔍 Searching for the best match for: " + query);
  const results = await vectorStore.similaritySearch(query, 1);

  console.log(`\n✅ Recommended product: "${results[0].pageContent}"`);
  //console.log(`   Similarity score: ${score.toFixed(3)}\n`);

  process.stdout.write(prompt);
}

Enter fullscreen mode Exit fullscreen mode

Code deep dive: how semantic search comes to life

Now that we’ve explored the concept of searching by meaning, let’s look under the hood of our JavaScript + LangChain + Ollama implementation.

The full source code is in the previous section, but here’s a closer look at the key building blocks that make this small but powerful semantic search engine work.

1. Initializing the embedding model

const embeddings = new OllamaEmbeddings({
  model: "nomic-embed-text",
  baseUrl: "http://localhost:11434",
});
Enter fullscreen mode Exit fullscreen mode

This line connects our application to Ollama, which runs locally and provides access to the nomic-embed-text model, a model specialized in generating text embeddings.

Each product description and user query is transformed into a vector (an array of numbers).
These vectors represent semantic meaning, enabling us to compare concepts mathematically rather than relying on keywords.

Why it matters: choosing the right embedding model is crucial, it defines the “semantic understanding” of your search. Different models specialize in different languages, domains, or text lengths. With Ollama, you can test models locally, eliminating the need for cloud APIs or network latency.

2. Defining the product catalog

const productDescriptions = [
  "Wireless Bluetooth headphones with noise cancellation...",
  "Ergonomic office chair with lumbar support...",
  "Compact dehumidifier for small rooms and closets.",
  // ...
];
Enter fullscreen mode Exit fullscreen mode

In our demo, the product catalog is just a static JavaScript array for simplicity.
But in a real-world scenario, you’d load this data dynamically from an API, a database, or a headless CMS like Storyblok.

That way, each product description or metadata entry can be automatically transformed into embeddings whenever your catalog updates.

Tip: if you use a CMS like Storyblok, you can schedule a background job to re-embed new or updated products and sync them with your vector database, or you can use the WebHooks for triggering the re-indexing of the published content.

3. Creating the Vector Store

const vectorStore = new MemoryVectorStore(embeddings);
Enter fullscreen mode Exit fullscreen mode

This initializes an in-memory vector database, a place to store the embeddings of your products.

In production, you’d use a persistent vector database (such as Pinecone, Weaviate, or Qdrant) to store and index your embeddings efficiently for large-scale searches.

Why it matters: the vector store is the engine behind semantic retrieval. It’s what allows your app to perform fast similarity searches and find the most relevant product for a user’s natural-language query.

4. Loading the products into the Vector Store

for (const productDescription of productDescriptions) {
  let document = new Document({ pageContent: productDescription });
  await vectorStore.addDocuments([document]);
  process.stdout.write(`✅`);
}
Enter fullscreen mode Exit fullscreen mode

Here, each product description is wrapped into a Document object, which LangChain uses as a standard structure for text data.
Then, we call addDocuments() to embed and store the product vector inside our MemoryVectorStore.

Behind the scenes: each time addDocuments() runs, LangChain asks the embedding model to generate a vector for that text. Those vectors are then indexed, ready to be compared to future user queries.

5. Performing the semantic search

const results = await vectorStore.similaritySearch(query, 1);
Enter fullscreen mode Exit fullscreen mode

When a user types something like:

“In my room there’s a lot of humidity.”

…the system creates an embedding for the query and compares it to all stored product embeddings using cosine similarity (LangChain similaritySearch method supports also other algorithms, but cosine algortihm for this example is enogh).
The closest vector, the one with the highest similarity score, is considered the best match.

In this case, the top result would likely be:

✅ “Compact dehumidifier for small rooms and closets.”

That’s how the system connects the intent (“humidity problem”) to the solution (a dehumidifier), even though the words don’t directly match.

6. From demo to real product discovery

The beauty of this approach is how easily it scales:

  • Swap the in-memory store for a real vector database.
  • Use a more powerful cloud model for calculating embeddings.
  • Sync product data automatically from your CMS.
  • Add metadata (such as price, category, and tags) to enrich your embeddings.
  • Combine it with an LLM to explain or summarize the recommended product.

You’ve now built the foundation of a semantic search system, one that doesn’t just look for keywords, but truly understands user needs.

Run the example

1. Prerequisites

2. Install dependencies

bun add @langchain/ollama @langchain/classic @langchain/core
Enter fullscreen mode Exit fullscreen mode

3. Pull the embedding model

ollama pull nomic-embed-text
Enter fullscreen mode Exit fullscreen mode

4. Run the script

bun run semantic-search-bun.js
Enter fullscreen mode Exit fullscreen mode

5. Try it out

🛒 What do you need? (type 'quit' to exit): My room has a lot of humidity
✅ Recommended product: "Compact dehumidifier for small rooms and closets."
Enter fullscreen mode Exit fullscreen mode

The value: from search to solution

This approach changes the entire dynamic of how users interact with products.

  • For users: it feels effortless and natural; they describe needs, not keywords.
  • For brands: it becomes a powerful way to guide users to the right solution.
  • For businesses: it’s a scalable, intelligent foundation for personalization across every channel.

It’s not just product search.
It’s solution discovery.

Closing Thoughts

This use case demonstrates how emerging technologies, such as vector databases and semantic embeddings, are shifting us from searching to understanding.

When paired with a modern CMS like Storyblok, they unlock experiences that are:

  • More human
  • More contextual
  • More valuable

We’re just at the beginning of this transformation, but the potential is enormous.

The next generation of search won’t just find things.
It will understand what we need.

Top comments (0)