stable-worldmodel-a-high-performance-platform-for-reproducible-world-model-research
Ayush Chaurasia
Quentin Lhoest
Lucas Maes
Quentin Le Lidec
reproducible-data-curation-in-the-multimodal-lakehouse
Prashanth Rao
newsletter-may-2026
ChanChan Mao
newsletter-april-2026
ChanChan Mao
how-lancedb-accelerates-vector-search-at-10-billion-scale
Yang Cen
opensearch-vs-lancedb-for-vector-search-query-cost-and-infrastructure
Justin Miller
volcano-engine-autonomous-driving-data-lake-solution
Kejian Ju
unifying-the-av-ml-stack-lancedb
Ayush Chaurasia
lance-json-support-why-you-might-not-really-need-variant
Jack Ye
building-a-storage-format-for-the-next-era-of-biology
Pavan Ramkumar
newsletter-march-2026
ChanChan Mao
smart-parsing-meets-sharp-retrieval-combining-liteparse-and-lancedb
Clelia Astra Bertelli
Prashanth Rao
lance-format-v2-2-benchmarks-half-the-storage-none-of-the-slowdown
Xuanwo
make-your-sql-workflows-multimodal-with-lancedb-x-duckdb
Prashanth Rao
agentic-coding-as-community-stewardship
Xuanwo
what-we-mean-by-multimodal
Prashanth Rao
ai-native-development-local-continue-lancedb
Ty Dunn
lance-file-format-2-2-taming-complex-data
Xuanwo
lance-blob-v2
Xuanwo
Jack Ye
openclaw-lancedb-memory-layer
Xuanwo
Prashanth Rao
openclaw-lancedb-seed2
LanceDB
openclaw-memory-from-zero-to-lancedb-pro
Prashanth Rao
upload-lance-datasets-to-hf-hub
Prashanth Rao
zero-shot-image-classification-with-vector-search
Vipul Maheshwari
werides-data-platform-transformation-how-lancedb-fuels-model-development-velocity
Qian Zhu
Fei Chen
training-a-variational-autoencoder-from-scratch-with-the-lance-file-format
LanceDB
track-ai-trends-crewai-agents-rag
LanceDB
tokens-per-second-is-not-all-you-need
Mingran Wang
Tan Li
the-future-of-open-source-table-formats-iceberg-and-lance
Jack Ye
the-case-for-random-access-i-o
LanceDB
series-a-funding
Chang She
semanticdotart
Ayush Chaurasia
second-dinners-secret-weapon-lancedb-powered-rag-for-faster-smarter-game-development
Qian Zhu
search-within-an-image-331b54e4285e
Kaushal Choudhary
scalable-computer-vision-with-lancedb-voxel51-d8b65066d5f6
LanceDB
rethinking-table-file-paths-lance-multi-base-layout
Jack Ye
rag-isnt-one-size-fits-all
Leonard Marcq
python-package-to-convert-image-datasets-to-lance-type
Vipul Maheshwari
one-million-iops
Weston Pace
november-feature-roundup
Will Jones
newsletter-september-2025
Jasmine Wang
newsletter-october-2025
Jasmine Wang
newsletter-november-2025
ChanChan Mao
newsletter-june-2025
David Myriel
newsletter-july-2025
Jasmine Wang
newsletter-january-2026
ChanChan Mao
newsletter-february-2026
ChanChan Mao
newsletter-december-2025
ChanChan Mao
newsletter-august-2025
Jasmine Wang
my-summer-internship-experience-at-lancedb-2
Raunak Sinha
my-simd-is-faster-than-yours-fb2989bf25e7
LanceDB
multimodal-myntra-fashion-search-engine-using-lancedb
LanceDB
multimodal-lakehouse
David Myriel
multi-document-agentic-rag-a-walkthrough
Vipul Maheshwari
modified-rag-parent-document-bigger-chunk-retriever-62b3d1e79bc6
Mahesh Deshwal
memgpt-os-inspired-llms-that-manage-their-own-memory-793d6eed417e
Ayush Chaurasia
late-interaction-efficient-multi-modal-retrievers-need-more-than-just-a-vector-index
Ayush Chaurasia
lancedb-x-continue
LanceDB
lance-x-huggingface-a-new-era-of-sharing-multimodal-data
Prashanth Rao
Quentin Lhoest
Xuanwo
Ayush Chaurasia
lance-x-duckdb-sql-retrieval-on-the-multimodal-lakehouse-format
Xuanwo
lance-windows-windows-lance
Chang She
lance-v2
Weston Pace
lance-namespace-lancedb-and-ray
Jack Ye
lance-file-2-1-stable
Weston Pace
lance-file-2-1-smaller-and-simpler
Weston Pace
lance-data-viewer
Gordon Murray
lance-community-governance
Jack Ye
introducing-lance-namespace-spark-integration
Jack Ye
implementing-corrective-rag-in-the-easiest-way-2
LanceDB
hybrid-search-rag-for-real-life-production-grade-applications-e1e727b3965a
Mahesh Deshwal
hybrid-search-combining-bm25-and-semantic-search-for-better-results-with-lan-1358038fe7e6
LanceDB
hybrid-search-and-custom-reranking-with-lancedb-4c10a6a3447e
LanceDB
how-to-reduce-hallucinations-from-llm-powered-agents-using-long-term-memory-72f262c3cc1f
Tevin Wang
guide-to-use-contextual-retrieval-and-prompt-caching-with-lancedb
LanceDB
grpo-understanding-and-fine-tuning-the-next-gen-reasoning-model-2
Mahesh Deshwal
graphrag-hierarchical-approach-to-retrieval-augmented-generation
Akash Desai
gpu-accelerated-indexing-in-lancedb-27558fa7eee5
LanceDB
geo-support
Jack Ye
geneva-twelvelabs
David Myriel
geneva-feature-engineering
Jonathan Hsieh
from-bi-to-ai-lance-and-iceberg
Jack Ye
Prashanth Rao
fluss-integration
Wayne Wang
file-readers-in-depth-parallelism-without-row-groups
Weston Pace
feature-rabitq-quantization
David Myriel
Yang Cen
feature-full-text-search
David Myriel
enhance-rag-integrate-contextual-compression-and-filtering-for-precision-a29d4a810301
Kaushal Choudhary
effortlessly-loading-and-processing-images-with-lance-a-code-walkthrough
LanceDB
designing-a-table-format-for-ml-workloads
Weston Pace
custom-dataset-for-llm-training-using-lance
LanceDB
creating-a-fintech-agent
Vipul Maheshwari
convert-any-image-dataset-to-lance
LanceDB
columnar-file-readers-in-depth-structural-encoding
Weston Pace
columnar-file-readers-in-depth-repetition-definition-levels
Weston Pace
columnar-file-readers-in-depth-compression-transparency
Weston Pace
columnar-file-readers-in-depth-column-shredding
Weston Pace
columnar-file-readers-in-depth-backpressure
Weston Pace
columnar-file-readers-in-depth-apis-and-fusion
Weston Pace
chunking-techniques-with-langchain-and-llamaindex
Prashant Kumar
chunking-analysis-which-is-the-right-chunking-approach-for-your-language
Shresth Shukla
chat-with-csv-excel-using-lancedb
LanceDB
case-study-netflix
David Myriel
case-study-dosu
Qian Zhu
Michael Ludden
case-study-cognee
David Myriel
Vasilije Markovic
case-study-coderabbit
Qian Zhu
building-rag-on-codebases-part-2
Sankalp Shubham
building-rag-on-codebases-part-1
Sankalp Shubham
branching-and-shallow-clone
Jack Ye
better-rag-with-active-retrieval-augmented-generation-flare-3b66646e2a9f
LanceDB
benchmarking-random-access-in-lance
Chang She
benchmarking-lancedb-92b01032874a-2
LanceDB
benchmarking-cohere-reranker-with-lancedb
LanceDB
anythingllms-competitive-edge-lancedb-for-seamless-rag-and-agent-workflows
Ayush Chaurasia
announcing-lance-sdk
Weston Pace
agentic-rag-using-langgraph-building-a-simple-customer-support-autonomous-agent
LanceDB
advanced-rag-precise-zero-shot-dense-retrieval-with-hyde-0946c54dfdcb
LanceDB
accelerate-vector-search-applications-using-openvino-lancedb
LanceDB
a-primer-on-text-chunking-and-its-types-a420efc96a13
Prashant Kumar
a-practical-guide-to-training-custom-rerankers
Ayush Chaurasia
a-practical-guide-to-fine-tuning-embedding-models
Ayush Chaurasia
keep-your-data-fresh-with-cocoindex-and-lancedb
Prashanth Rao
Linghua Jin

Multimodal Myntra Fashion Search Engine Using LanceDB

March 20, 2024
Engineering

In this comprehensive guide, we aim to explain the process of creating a multi-modal search app and break it down into manageable steps. The procedure involves several phases, including registering clip embeddings, setting up a data class and table, and executing a search query.

Using a vector database like LanceDB allows us to efficiently handle large volumes of data, paving the way for robust and efficient vector search. Clip embeddings, an integral part of our process, convert the images into embeddings that can be recognized by the vector database.

We’ll also create a Streamlit app, which offers a more user-friendly GUI to access and use the search engine.

By the end of this blog, you should have a clear understanding of how to use LanceDB to create your own search engine, regardless of your dataset or use case. With LanceDB, you can see how simple it is to set up and query a vector database. Most of the boilerplate code is handled by LanceDB itself. Let’s dive in.

To create the search engine, these are the steps we will be following -

  1. Define the Embedding Function - We will use OpenAI CLIP to create the embeddings using EmbeddingFunctionRegistry for the images.
  2. Define the Schema - We define the table schema.
  3. Create the Table - We create the vector database using the embedding function and schema.
  4. Search the Query - We can now do a multimodal vector search in the database.
  5. Streamlit App - For a GUI

Download the data

First, we will download the Myntra Fashion Product Dataset from Kaggle and store it in the input folder. The folder shall contain the Images directory along with the Fashion Dataset.csv file. The dataset contains about 14.5K images, for the purpose of this blog we only take a 1000 samples out of it. For a more comprehensive search, you can increase the number of samples.

1. Register CLIP embedding

To store the images in the form of a vector database, we first need to convert them to embeddings. There are many ways to do this within LanceDB.

LanceDB supports 3 methods of working with embeddings.

  1. You can manually generate embeddings for the data and queries. This is done outside of LanceDB.
  2. You can use the built-in embedding functions to embed the data and queries in the background (this is explained below)
  3. For Python users, you can define your own custom embedding function , which extends the default embedding function.

For this project, we use the embedding function. We define a global embedding function registry with the OpenAI CLIP model. With the EmbeddingFunctionRegistry, you can generate embeddings with just a few lines of code.

from lancedb.embeddings import EmbeddingFunctionRegistry

def register_model(model_name):
    registry = EmbeddingFunctionRegistry.get_instance()
    model = registry.get(model_name).create()
    return model

2. Define the schema

The embedding function defined above abstracts model and dimension details required to define the schema. A schema tells LanceDB the structure of the table.

For this project, we will define the schema with two fields -

  1. Vector Field - VectorField tells LanceDB to use the CLIP embedding function to generate query embeddings for the vector column
  2. Source Field - SourceField ensures that when adding data, we automatically use the specified embedding function to encode image_uri
from PIL import Image
from lancedb.pydantic import LanceModel, Vector

clip = register_model("open-clip")

class Myntra(LanceModel):
    vector: Vector(clip.ndims()) = clip.VectorField()
    image_uri: str = clip.SourceField()

    @property
    def image(self):
        return Image.open(self.image_uri)

3. Create the table

Now that we have our embedding function and schema, we will create the table.

import lancedb
import pandas as pd
from pathlib import Path
from random import sample
import argparse

def create_table(database, table_name, data_path, schema=Myntra, mode="overwrite"):

    # Connect to the LanceDB database
    db = lancedb.connect(database)

    # Check if the table already exists in the database
    if table_name in db:
        print(f"Table {table_name} already exists in the database")
        table = db[table_name]

    # if it does not exist then create a new table
    else:

        print(f"Creating table {table_name} in the database")

        # Create the table with the given schema
        table = db.create_table(table_name, schema=schema, mode=mode)

        # Define the Path of the images and obtain the Image uri
        p = Path(data_path).expanduser()
        uris = [str(f) for f in p.glob("*.jpg")]
        print(f"Found {len(uris)} images in {p}")

        # Sample 1000 images from the data
        # Select more samples for a wider search
        uris = sample(uris, 1000)

        # Add the data to the table
        print(f"Adding {len(uris)} images to the table")
        table.add(pd.DataFrame({"image_uri": uris}))
        print(f"Added {len(uris)} images to the table")

One thing to note is that you do not need to create the embeddings separately when using the embedding function; LanceDB takes care of that automatically.

4. Query the table

Now you can open and query the table

# Connect to the Database and open the table
db = lancedb.connect("~/.lancedb")
table = db.open_table(table_name)

The OpenCLIP query embedding function supports querying via both text and images. We will make this project multimodal by providing text and image search.

def run_vector_search(database, table_name, schema, search_query, limit=6, output_folder="output"):
    if os.path.exists(output_folder):
        for file in os.listdir(output_folder):
            os.remove(os.path.join(output_folder, file))
    else:
        os.makedirs(output_folder)

    db = lancedb.connect(database)
    table = db.open_table(table_name)
    rs = table.search(search_query).limit(limit).to_pydantic(schema)

    for i in range(limit):
        image_path = os.path.join(output_folder, f"image_{i}.jpg")
        rs[i].image.save(image_path, "JPEG")

5. Build the Streamlit app

Once this is done, we create a Streamlit app to build an interface.

import os
import argparse
import streamlit as st
from PIL import Image

def main(args):
    # Define the title and sidebar options
    st.sidebar.title('Vector Search')
    table_name = st.sidebar.text_input('Name of the table', args.table_name)
    search_query = st.sidebar.text_input('Search query', args.search_query)
    limit = st.sidebar.slider('Limit the number of results', args.limit_min, args.limit_max, args.limit_default)
    output_folder = st.sidebar.text_input('Output folder path', args.output_folder)

    # Image Based Search
    # Add an option for uploading an image for query
    uploaded_image = st.sidebar.file_uploader('Upload an image')
    if uploaded_image is not None:
        image = Image.open(uploaded_image)
        st.sidebar.image(image, caption='Uploaded Image', use_column_width=True)
        search_query = image  # Set the search query as the uploaded image

    # Run the vector search when the button is clicked
    if st.sidebar.button('Run Vector Search'):
        run_vector_search("~/.lancedb", table_name, Myntra, search_query, limit, output_folder)

    # Initialize session state for image index if it doesn't exist
    if 'current_image_index' not in st.session_state:
        st.session_state.current_image_index = 0

    # Display images in output folder
    if os.path.exists(output_folder):
        image_files = [f for f in os.listdir(output_folder) if f.endswith('.jpg') or f.endswith('.png')]
        if image_files:
            # Ensure the current index is within the bounds of available images
            num_images = len(image_files)
            st.session_state.current_image_index %= num_images
            image_file = image_files[st.session_state.current_image_index]
            image_path = os.path.join(output_folder, image_file)
            image = Image.open(image_path)
            st.image(image, caption=image_file, use_column_width=True)

            # Navigation buttons for previous and next images
            col1, col2 = st.columns(2)
            with col1:
                if st.button('Previous'):
                    st.session_state.current_image_index = (st.session_state.current_image_index - 1) % num_images
            with col2:
                if st.button('Next'):
                    st.session_state.current_image_index = (st.session_state.current_image_index + 1) % num_images
        else:
            st.write("No images found in the output folder.")

Demo

Conclusion

In conclusion, using LanceDB to create a multimodal fashion search engine for Myntra simplifies the process and improves efficiency. By taking advantage of capabilities such as vector search, automatic handling of embeddings, and the capacity to handle large volumes of data, we can streamline the development process and create a powerful tool for fashion search. Whether you’re a seasoned programmer or a beginner, this guide offers a comprehensive walkthrough of the process, making it accessible. It underlines the power and simplicity of using LanceDB and serves as a stepping stone for creating your own search engines for different datasets or use cases.

Resources

Contact

For queries and doubts, you can reach out to me on

Stable-Worldmodel: A High Performance Platform for Reproducible World Model Research

Ayush Chaurasia
Quentin Lhoest
Lucas Maes
Quentin Le Lidec
June 2, 2026
stable-worldmodel-a-high-performance-platform-for-reproducible-world-model-research

🌍 Lance-Backed World Model Platform, 🦆 Multimodal SQL with Lance DuckDB Extension, 💰 LanceDB vs OpenSearch Cost Breakdown

ChanChan Mao
May 28, 2026
newsletter-may-2026

Reproducible Data Curation In The Multimodal Lakehouse

Prashanth Rao
May 29, 2026
reproducible-data-curation-in-the-multimodal-lakehouse