Build a Vector Database with Milvus Using Python
In this article, we’re building a vector database using Milvus with Python, and you’ll see why adopting this approach can save your small team countless hours of work.
Prerequisites
- Python 3.11+
- Milvus Docker version 2.2.x
- Pip install pymilvus>=2.2.0
- Docker installed on your machine
Step 1: Setting up Milvus
First, you need to set up Milvus. The simplest way to do that is through Docker.
docker run -d --name milvus \
-p 19530:19530 \
-p 19121:19121 \
-e MILVUS_ENV=production \
milvusdb/milvus:v2.2.0-cpu-d016e42
Why Docker? It’s like a time machine for your setup — no more worrying about your local environment or OS incompatibilities. If you run into connection issues, make sure your Docker daemon is up and running.
Step 2: Install the Python SDK
The Milvus Python SDK makes it easy to communicate with the Milvus server from your Python applications. Here’s how to install it:
pip install pymilvus==2.2.0
If you see an error related to permissions, try running the command with sudo or set up a virtual environment. Permissions can be a nightmare when you’re just trying to install a package.
Step 3: Connect to Milvus
Now, let’s connect your Python application to the Milvus database. Here’s how to do it:
from pymilvus import Collection, connections
# Establishing a connection
connections.connect("default", host="localhost", port="19530")
This line of code establishes a basic connection. If you run into connection errors, check your Docker container is healthy by running docker ps.
Step 4: Creating a Collection
A collection in Milvus is like a table in SQL. You’ll want to define your schema when you create it.
from pymilvus import FieldSchema, CollectionSchema
# Define schema
fields = [
FieldSchema(name="id", dtype="INT64", is_primary=True, auto_id=True),
FieldSchema(name="vector", dtype="FLOAT_VECTOR", dim=128),
FieldSchema(name="metadata", dtype="VARCHAR", max_length=100)
]
schema = CollectionSchema(fields=fields, description="test collection")
collection = Collection(name="example_collection", schema=schema)
This example defines a simple schema. I once tried to define a schema without considering vector dimensions—my vectors ended up being 64D when I needed 128D. Oops!
Step 5: Inserting Data
With your collection in place, it’s time to insert some data. You can generate random data for testing.
import numpy as np
# Generate random vectors
vectors = np.random.rand(10, 128).tolist()
metadata = ["sample_" + str(i) for i in range(10)]
data = [
[None]*10, # for dynamic ids
vectors,
metadata
]
# Insert into collection
collection.insert(data)
After you run this code, check the collection to ensure the insertion was successful. If you don’t see your vectors, double-check your data format.
Step 6: Querying the Collection
Now for the fun part: querying your data. You can search for the nearest neighbors of a given vector.
query_vector = np.random.rand(128).tolist()
# Search for nearest neighbors
results = collection.search(
data=[query_vector],
anns_field="vector",
param={"metric_type": "L2", "nprobe": 10},
limit=5
)
for result in results:
print(result.entities)
This search function returns the closest vectors to your query. Make sure your query vector is the same dimension as your stored vectors. If the dimensions mismatch, you’ll face an IndexError — trust me, been there and got the T-shirt!
The Gotchas
- Connection Issues: Sometimes, you might have connection problems because your Docker container isn’t running or your firewall is blocking ports.
- Data Format Errors: Ensure all your data (especially vectors) are in the correct format. A wrong format will lead to confusing error messages.
- Performance Tuning: If you’re working with large datasets, not configuring nprobe can lead to slower searches. Always test for performance.
- Memory Management: Inserting massive amounts of data at once might lead to memory issues. Insert in chunks for stability.
Full Code Example
from pymilvus import Collection, FieldSchema, CollectionSchema, connections
import numpy as np
# Setup connection
connections.connect("default", host="localhost", port="19530")
# Define and create collection schema
fields = [
FieldSchema(name="id", dtype="INT64", is_primary=True, auto_id=True),
FieldSchema(name="vector", dtype="FLOAT_VECTOR", dim=128),
FieldSchema(name="metadata", dtype="VARCHAR", max_length=100)
]
schema = CollectionSchema(fields=fields, description="test collection")
collection = Collection(name="example_collection", schema=schema)
# Insert random data
vectors = np.random.rand(10, 128).tolist()
metadata = ["sample_" + str(i) for i in range(10)]
data = [
[None]*10,
vectors,
metadata
]
collection.insert(data)
# Perform a search
query_vector = np.random.rand(128).tolist()
results = collection.search(data=[query_vector], anns_field="vector", param={"metric_type": "L2", "nprobe": 10}, limit=5)
for result in results:
print(result.entities)
What’s Next
Now that you have a basic setup, consider expanding your database by integrating it with a machine learning model. You could create a recommendation system using your Milvus database.
FAQ
- How does Milvus handle large datasets? Milvus is built for scalability, but you’ll want to monitor resources and optimize queries based on your dataset sizes.
- Can I use Milvus for real-time applications? Yes, but latency might be higher if you have lots of complex queries running simultaneously.
- What if I run into installation issues? Check the Milvus documentation for troubleshooting steps and common issues.
Data Sources
For more about Milvus, visit the following:
| Repository | Stars | Forks | Open Issues | License | Last Updated |
|---|---|---|---|---|---|
| milvus-io/milvus | 43,819 | 3,964 | 1,178 | Apache-2.0 | 2026-04-16 |
Last updated April 16, 2026. Data sourced from official docs and community benchmarks.
🕒 Published: