VectorDB#

VectorDB interface allows to insert vector embeddings into a Vector Database. These records can then later be queried for nearest neighbour search, and return back similar records found in the database.

To insert and query the records, we have to do the following -

  1. Create embeddings for our nodes

  2. Insert the embeddings along with node metadata into the vector database

  3. Take an input query and embed it into a vector embedding

  4. Query the VectorDB with input embedding and get similar node back from VectorDB

We have already covered task #1 on how to convert a Node into an embedding in the Embedder guide. In this guide we are going to try out task #2, #3, and #4.

For this we need to:

  1. Prepare our Node embeddings as we did in the Embedder guide

  2. Get an instance of VectorDB using the get_vector_db method, along with its configuration

  3. Insert our nodes into the vector database using the upsert method

  4. Embed an input query using the same Embedder

  5. Query the VectorDB using the query method

For this Getting Started guide, we are going to use Qdrant in-memory vector database. Let’s get started.

Setup#

  1. Ensure bodhilib is installed.

  2. For VectorDB, we are going to use Qdrant. To use Qdrant with bodhilib, we will install the plugin bodhiext.qdrant.

[1]:
!pip install -q bodhilib bodhiext.sentence_transformers bodhiext.qdrant
[2]:
# prepare the node embeddings for the Paul Graham's essay:
# 1. Load the Paul Graham essays from data/data-loader directory using `file` DataLoader
# 2. Convert it into Nodes using sentence_splitter
# 3. Enrich node embeddings using the sentence_transformers
import os
from pathlib import Path
from bodhilib import get_data_loader, get_splitter, get_embedder

# Get data directory path and add it to data_loader
current_dir = current_working_directory = Path(os.getcwd())
data_dir = current_dir / ".." / "data" / "data-loader"
data_loader = get_data_loader('file')
data_loader.add_resource(dir=str(data_dir))
docs = data_loader.load()
splitter = get_splitter("text_splitter", max_len=300, overlap=30)
nodes = splitter.split(docs)
embedder = get_embedder("sentence_transformers")
_ = embedder.embed(nodes)
[3]:
# Get an instance of Vector DB
from bodhilib import get_vector_db

vector_db = get_vector_db("qdrant", location=":memory:")
[4]:
# setup the collection in vector db
from bodhilib import Distance

collection_name = "test_collection"
if "test_collection" in vector_db.get_collections():
    vector_db.delete_collection("test_collection")
vector_db.create_collection(collection_name=collection_name, dimension=embedder.dimension, distance=Distance.COSINE)
[4]:
True
[5]:
# insert the Node embeddings and return database enriched Node object

_ = vector_db.upsert(collection_name, nodes)
[6]:
# the nodes object has been enriched with database record identifier `id`
print(nodes[0].id)
6c32ca63-87c6-48fb-be38-afd25ee88690
[7]:
# Embed the input query using Embedder
input_query = "According to Paul Graham, how to tackle when you are in doubt?"
embedding = embedder.embed(input_query)
[8]:
# query the vector db using the input embedding
result = vector_db.query(collection_name, embedding[0].embedding, limit=5)
[9]:
import textwrap

print(textwrap.fill(result[0].text, 100))
who sits back and offers sophisticated-sounding criticisms of them. "It's easy to criticize" is true
in the most literal sense, and the route to great work is never easy.  There may be some jobs where
it's an advantage to be cynical and pessimistic, but if you want to do great work it's an advantage
to be optimistic, even though that means you'll risk looking like a fool sometimes. There's an old
tradition of doing the opposite. The Old Testament says it's better to keep quiet lest you look like
a fool. But that's advice for seeming smart. If you actually want to discover new things, it's
better to take the risk of telling people your ideas.  Some people are naturally earnest, and with
others it takes a conscious effort. Either kind of earnestness will suffice. But I doubt it would be
possible to do great work without being earnest. It's so hard to do even if you are. You don't have
enough margin for error to accommodate the distortions introduced by being affected, intellectually
dishonest, orthodox, fashionable, or cool. [14]      Great work is consistent not only with who did
it, but with itself. It's usually all of a piece. So if you face a decision in the middle of working
on something, ask which choice is more consistent.  You may have to throw things away and redo them.
You won't necessarily have to, but you have to be willing to. And that can take some effort; when
there's something you need to redo, status quo bias and laziness will combine to keep you in denial
about it. To beat this ask: If I'd already made the change, would I want to revert to what I have
now?  Have the confidence to cut.

🎉 We just inserted and queried our document using VectorDB.

Next, let’s see how we build a complex Extractive Q&A flow using all these components in our Extractive QnA lab.