MongoDB Hybrid Search

Combine vector and keyword retrieval with SearchType.hybrid on a MongoDB collection.

Code

mongo_db_hybrid_search.py
import typer
from agno.agent import Agent
from agno.knowledge.knowledge import Knowledge
from agno.vectordb.mongodb import MongoVectorDb
from agno.vectordb.search import SearchType
from rich.prompt import Prompt

mdb_connection_string = "mongodb://localhost:27017"

vector_db = MongoVectorDb(
    collection_name="recipes",
    db_url=mdb_connection_string,
    search_index_name="recipes",
    search_type=SearchType.hybrid,
)

knowledge_base = Knowledge(
    vector_db=vector_db,
)

knowledge_base.insert(
    name="Recipes",
    url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf",
    metadata={"doc_type": "recipe_book"},
)

def mongodb_agent(user: str = "user"):
    agent = Agent(
        user_id=user,
        knowledge=knowledge_base,
        search_knowledge=True,
    )

    while True:
        message = Prompt.ask(f"[bold]{user}[/bold]")
        if message in ("exit", "bye"):
            break
        agent.print_response(message)

if __name__ == "__main__":
    typer.run(mongodb_agent)

Usage

Set up your virtual environment

uv venv --python 3.12
source .venv/bin/activate

Install dependencies

uv pip install -U pymongo typer rich pypdf openai agno

Run MongoDB

docker run -d \
--rm \
--name mongodb-container \
-p 27017:27017 \
-v ./tmp/mongo-data:/data/db \
mongodb/mongodb-atlas-local:8.0.3

Create the keyword search index

Hybrid search requires a keyword Search index named default in addition to the vector index Agno creates. Wait for MongoDB, create the collection if needed, then create the index and wait until it is queryable:

until [ "$(docker inspect --format='{{.State.Health.Status}}' mongodb-container)" = "healthy" ]; do
  sleep 1
done

docker exec mongodb-container mongosh --quiet --eval '
const database = db.getSiblingDB("agno");
if (!database.getCollectionNames().includes("recipes")) {
  database.createCollection("recipes");
}
if (!database.recipes.aggregate([
  { $listSearchIndexes: { name: "default" } }
]).hasNext()) {
  database.recipes.createSearchIndex("default", {
    mappings: {
      dynamic: false,
      fields: { content: { type: "string" } }
    }
  });
}
while (!database.recipes.aggregate([
  { $listSearchIndexes: { name: "default" } }
]).toArray()[0]?.queryable) {
  sleep(1000);
}
'

Set environment variables

export OPENAI_API_KEY=xxx

Run Agent

python mongo_db_hybrid_search.py