Building a Semantic Search Engine with Next.js and Elasticsearch

April 28, 2025
Next.js
Elasticsearch
Search
NLP
Web Development

In this article, I'll share my experience building CozyBible.com, a semantic search engine for Bible verses using Next.js, Django, and Elasticsearch.

Why Semantic Search?

Traditional keyword search is limited - it only finds exact matches. Semantic search understands the meaning behind queries, providing more relevant results even when the exact words aren't present.

Architecture Overview

Our application consists of three main components:

  • Next.js frontend for the user interface
  • Django REST API for business logic
  • Elasticsearch for indexing and searching

Text Embeddings

The key to semantic search is text embeddings - numerical representations of text that capture meaning. We used a pre-trained model to convert Bible verses into vector embeddings.

Indexing in Elasticsearch

Elasticsearch stores these vector embeddings and enables efficient similarity searches. Here's a simplified example of our indexing process:


      # Python code for indexing documents with embeddings
      def index_document(text, embedding):
          doc = {
              'text': text,
              'embedding': embedding
          }
          es.index(index='bible_verses', body=doc)
      

Building the Search API

Our Django REST API handles the search logic, converting user queries into embeddings and finding similar verses.

Next.js Frontend

The frontend provides a clean, intuitive interface for users to enter natural language queries and view results.

Performance Optimization

To ensure fast search results, we implemented:

  • Efficient vector indexing in Elasticsearch
  • API response caching
  • Client-side state management

Conclusion

Building a semantic search engine is a fascinating project that combines NLP, search technology, and modern web development. The result is a much more intuitive and powerful search experience for users.