Momento announces $15M Series A funding. Topics event bus released for general availability. Read more →
September 12, 2023 - 4 Min Read

Getting started with search on a Vector Index

Utilize the power of a vector index for lightning-fast search capabilities.

Ellery Addington-White
Author

Share

Important notice: Momento Vector Index has been deprecated in April of 2024.

With the exponential growth of the information we have, building a search system is a vital tool for the modern day engineer. Building a search capability into your website can be intimidating and expensive, requiring you to set up dedicated infrastructure just to index your data and search it.

In this series we are going to teach you how to build a quick but powerful search system without breaking the bank. Starting with basic search and continuing to add and improve on it as the series continues. The secret tools we are going to use to power this search are a large language model and a vector index.

A vector index is a powerful tool for storing and managing data in the form of vectors. The direction of each vector encodes essential attributes and features of the data. These data stores play a crucial role in enabling advanced functionalities such as reverse image search and empowering AI chatbots. 

While the concept of vector indexes might initially appear complex and intimidating, Momento has simplified the process. Surprisingly, with just a few lines of code, vector indexes can seamlessly replace many of the search capabilities you rely on. Let’s delve deeper into this exciting technology.

Architecture

For our test app we are going to be building a simple movie catalog service that allows you to search for movies by their titles and descriptions(I got the dataset from here). You’ll end up with an architecture that looks like this:

Creating a vector from text

For this tutorial we are going to be using Sentence Transformers all-MiniLM-L6-v2 model which is a general purpose model for generating embeddings(vectors) from some input text. We are going to write a quick utility function get_embedding to make this request for us.

from sentence_transformers import SentenceTransformer, util

def get_embedding(i):
	model = SentenceTransformer("all-MiniLM-L6-v2")
	model.max_seq_length = 256
	return model.encode(i, normalize_embeddings=True)

   )

Ingesting your data into the index

Next up, let’s scan our movies.csv data file and for each item we get the embedding and insert it into our Momento Vector Index. The code to do that will look like this

import pandas as pd
from examples.moviesearch.util import get_embedding
from momento import (
	CredentialProvider,
	PreviewVectorIndexClient,
	VectorIndexConfigurations,
)
from momento.requests.vector_index import Item

from momento.responses.vector_index import (
	UpsertItemBatch,
)
# Instantiate Momento Vector Client
client = PreviewVectorIndexClient(
   VectorIndexConfigurations.Default.latest(),
   CredentialProvider.from_environment_variable("AUTH_TOKEN")
)


# Read CSV data of movies into dataframe
df = pd.read_csv('~/Downloads/movies_metadata.csv', low_memory=False).head(n=100)


# Get embeddings for each movie from open AI
items_to_be_indexed = []
for index, row in df.iterrows():
   items_to_be_indexed.append(Item(
       vector=get_embedding(str(row['title']) + " " + str(row['overview'])),
       id=str(index),
       metadata={
           'title': row['title']
       }
   ))

# Delete and recreate index on momento
client.delete_index(index_name='movies')
client.create_index(
   index_name='movies',
   # base num of dimensions off first vector we want to insert
   num_dimensions=len(items_to_be_indexed[0].vector)  
)

# add items into momento
rsp = mvi_client.upsert_item_batch("movies", items_to_be_indexed)


try:
   assert isinstance(rsp, UpsertItemBatch.Success)
except:
   print(add_rsp)

Search Data

Now that we have our data loaded into our index we can search it easily with a plain text query. For example, here I’m going to search for movies with “dogs”.

from examples.moviesearch.util import get_embedding
from momento import (
	CredentialProvider,
	PreviewVectorIndexClient,
	VectorIndexConfigurations,
)
from momento.responses.vector_index import Search

client = PreviewVectorIndexClient(
   VectorIndexConfigurations.Default.latest(),
   CredentialProvider.from_environment_variable("AUTH_TOKEN")
)

rsp = client.search(
   index_name='movies',
   query_vector=get_embedding("dog"),
   top_k=10,
   metadata_fields=['title']
)

assert isinstance(rsp, Search.Success)
for result in rsp.hits:
   print(
       f"{result.metadata['title']}: {round(result.distance, 3)}"
   )

When we run this we get the following output:

Babe: 0.784
Balto: 0.779

You can see our top 2 results were both movies about dogs Babe and Balto 🐕.

Conclusion and Next steps

That’s it! Now you have added a basic search capability to your stack in just a few minutes!

Stay tuned for the upcoming blogs in this series where we will learn how to:

  • Measure the quality of our search
  • Tune how we pass input data to the embedding function for more accurate results
  • Add additional data to be indexed for movies
  • Use multiple indexes and assign different weights to certain fields
  • Inject business logic into your search ex: recommend more scary movies at night!
  • Bring your own model
  • Adding in caching to help with scaling.

Share