Skip to content
BotServBotServ
WeaviateVector databaseGraphQLHybrid SearchRAGLocal AI

Weaviate: Vector Database with GraphQL API

Weaviate vector database: installation, GraphQL API, hybrid search, modules. Use Weaviate for RAG. Practical guide with examples.

S

schutzgeist

11 min read
Weaviate: Vector Database with GraphQL API

Weaviate: Vector Database with GraphQL API

What this article covers

  • What Weaviate is and which features set it apart from other vector databases
  • How to install and run Weaviate locally with Docker
  • How to design schemas, store data, and perform search queries via GraphQL
  • How hybrid search works and why it’s valuable for RAG
  • How Weaviate compares to Chroma and Qdrant, and when to choose it

Introduction

You’re working with local RAG and may have already tried Chroma or Qdrant. Now you’re looking for a vector database that offers more than pure vector search. A database built from the ground up for semantic queries, equipped with a powerful query language.

That’s where Weaviate comes in. Weaviate is an open-source vector database distinguished by its GraphQL API, modular system, and built-in hybrid search. Rather than just storing vectors and finding similar ones, Weaviate provides a thoughtful architecture that combines vectorization, filtering, and hybrid search in a single system.

This article walks you through installation, schema design, data storage, and queries step by step. If you haven’t yet covered RAG fundamentals, read that first. Background on embedding models is also helpful.

Why do you need Weaviate?

Imagine running a knowledge base with thousands of documents. Some questions answer well through semantic similarity, that is, vector search. Others contain specific keywords or proper names that pure vector search struggles to find. So you’d need both: vector and keyword search in a single query.

With most vector databases, you must choose one approach or wire up external tools like BM25. Weaviate includes hybrid search out of the box. You weight vector and keyword search in a single query and get results that combine both worlds.

Then there’s the GraphQL API. Instead of learning a proprietary REST interface, you use a standardized query language many developers already know. You can express complex filters, sorting, and relationships between data objects in a single query. That’s especially valuable when your RAG application blends structured metadata with unstructured text.

The modular system is another strength. Weaviate can compute embeddings directly on the server if you enable a module like text2vec-transformers. You send raw text to Weaviate, and the database handles vectorization for you. For local setups, you can also supply your own vectors, which we’ll cover in this article.

Weaviate explained briefly

Weaviate stores data as objects with properties and vectors. Each object belongs to a class you define in the schema. The schema is like a table structure in a relational database: you specify which fields a class has, their data types, and whether they should be vectorized.

During a search query, Weaviate converts the query into a vector, compares it against stored vectors, and returns the most similar objects. That’s classic vector search. With hybrid search, Weaviate combines this vector search with keyword search and weights both according to a parameter you control.

The GraphQL API is the main interface for all queries. You write GraphQL queries to fetch, filter, and search objects. For writing and updating objects, you use the REST API or the Python client, which abstracts both for you.

Who this article is for

This article targets developers already familiar with RAG and vector databases. You should understand what local AI is and how RAG works. If you’ve already experimented with Chroma or Qdrant, this article is the logical next step. You need basic Python skills and should know how to use Docker, since we’ll run Weaviate in a Docker container.

Key terms

TermExplanation
ClassA category of data objects, similar to a table. Each class has defined properties.
SchemaThe definition of all classes, properties, and vectorizers. Created before storing data.
ObjectA single record within a class, consisting of properties and a vector.
VectorA numerical array representing the semantic content of an object.
ModuleA plugin that handles vectorization or other functions, such as text2vec-transformers.
Hybrid SearchA search method that combines and weights vector search and keyword search.
GraphQLA query language for making structured queries against Weaviate.
BM25An algorithm for keyword search based on term frequency and document length.
VectorizerA module that automatically converts text to vectors without requiring external embedding computation.

Installation: Starting Weaviate with Docker

Weaviate runs best in a Docker container. If you haven’t installed Docker yet, check out Docker fundamentals.

The simplest approach is a single Docker container without external modules. This configuration is ideal for getting started because you supply your own vectors and use Weaviate purely as storage and search engine.

docker run -d \
  --name weaviate \
  -p 8080:8080 \
  -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \
  -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \
  -v weaviate_data:/var/lib/weaviate \
  semitechnologies/weaviate:latest

Once running, you can reach Weaviate at http://localhost:8080. Check whether the server is running by calling the status endpoint:

curl http://localhost:8080/v1/.well-known/ready

If the response is READY, Weaviate is ready to use. The Docker volume weaviate_data ensures your data persists even after restarting the container.

For more complex setups with integrated vectorization modules, Docker Compose is recommended. Weaviate provides ready-made docker-compose.yml files that spin up additional containers for transformer models. For this article, the simple container is sufficient since we’re using our own vectors.

Installing the Python client

Weaviate provides an official Python client that abstracts the REST and GraphQL APIs. Install it with pip:

pip install weaviate-client

Then connect to your local Weaviate instance in Python:

import weaviate

client = weaviate.connect_to_local(
    host="localhost",
    port=8080
)

print(client.is_ready())  # True if the connection is established

The Python client uses the new v4 API, which offers a typed and more intuitive interface. If you find older tutorials using the v3 API, be aware that the syntax differs.

Designing the Schema

Before storing data, you create a schema that defines what classes exist and what properties they have. This is also where you decide whether Weaviate should vectorize automatically or if you’ll provide your own vectors.

In our example, we’re creating an Article class with title, content, and source properties. We’re skipping the internal vectorizer and bringing our own vectors instead.

from weaviate.classes.config import Configure

client.collections.create(
    name="Article",
    vectorizer_config=Configure.Vectorizer.none(),
    properties=[
        Configure.property(name="title", data_type=Configure.DataType.TEXT),
        Configure.property(name="content", data_type=Configure.DataType.TEXT),
        Configure.property(name="source", data_type=Configure.DataType.TEXT),
    ]
)

Setting Configure.Vectorizer.none() tells Weaviate to skip automatic vectorization. You supply the vectors yourself, computed with an external embedding model.

If you prefer to use a module like text2vec-transformers, you configure the vectorizer accordingly. However, this requires an additional container running the transformer model, which increases resource usage.

Storing Data

Now we add objects to the Article class. Since we disabled the internal vectorizer, we must provide vectors ourselves.

articles = client.collections.get("Article")

articles.data.insert_many([
    {
        "properties": {
            "title": "Was ist lokale KI?",
            "content": "Lokale KI läuft auf dem eigenen Rechner ohne Cloud-Dienste.",
            "source": "blog"
        },
        "vector": [0.12, 0.34, 0.56, 0.78]  # Dein Embedding-Vektor
    },
    {
        "properties": {
            "title": "RAG erklärt",
            "content": "RAG verbindet Dokumentensuche mit Sprachmodellen für bessere Antworten.",
            "source": "blog"
        },
        "vector": [0.23, 0.45, 0.67, 0.89]  # Dein Embedding-Vektor
    }
])

In practice, you generate vectors using an embedding model like intfloat/multilingual-e5-large or BAAI/bge-m3. The vector dimension must be consistent across all objects in a class. If you switch embedding models, you need to re-vectorize your data.

Performing Queries

Weaviate supports three search types: pure vector search, keyword search via BM25, and hybrid search. Let’s look at all three.

Vector Search

Vector search takes a query vector and returns the most similar objects:

articles = client.collections.get("Article")

results = articles.query.near_vector(
    near_vector=[0.15, 0.40, 0.60, 0.80],  # Dein Suchvektor
    limit=3
)

for obj in results.objects:
    print(obj.properties["title"], obj.properties["content"])

Keyword Search with BM25

BM25 search finds objects by keywords. It excels with proper nouns and specific terms:

results = articles.query.bm25(
    query="lokale KI",
    limit=3
)

for obj in results.objects:
    print(obj.properties["title"], obj.properties["content"])

Hybrid Search

Hybrid search merges vector search and BM25. The alpha parameter controls the weighting: alpha=0 is pure BM25, alpha=1 is pure vector search. A value of 0.5 weights both equally.

results = articles.query.hybrid(
    query="lokale KI",
    vector=[0.15, 0.40, 0.60, 0.80],  # Optional, can be generated automatically
    alpha=0.5,
    limit=3
)

for obj in results.objects:
    print(obj.properties["title"], obj.properties["content"])

Hybrid search is particularly valuable for RAG because many queries have both semantic and keyword-based components. Learn more in the hybrid search article.

Filtering

Weaviate lets you filter search results by properties, useful when you only want to search specific sources or time ranges.

from weaviate.classes.query import Filter

results = articles.query.near_vector(
    near_vector=[0.15, 0.40, 0.60, 0.80],
    limit=3,
    filters=Filter.by_property("source").equal("blog")
)

for obj in results.objects:
    print(obj.properties["title"], obj.properties["source"])

Filters combine with and_ and or_ to express complex conditions. This is more powerful than simple metadata filters in other databases.

Comparison: Weaviate vs. Chroma vs. Qdrant

FeatureWeaviateChromaQdrant
Query LanguageGraphQLPython APIREST and gRPC
Hybrid SearchBuilt-inLimitedVia Sparse Vectors
Automatic VectorizationYes, via modulesYes, via embedding functionsYes, via FastEmbed
SchemaExplicit, class-basedImplicit, collection-basedCollection-based
ScalingGood, distributed possibleSmall to mediumGood, production-ready
Learning CurveMediumVery lowLow to medium
GraphQLYesNoNo
FilteringVery powerful, composableSimpleVery powerful
Resource UsageMediumLowLow to medium

Weaviate shines when you need hybrid search without external tools and prefer GraphQL as your query language. Chroma is simpler for quick starts, Qdrant is more robust for pure vector search on large datasets. Weaviate offers the most features out of the box but requires more upfront learning.

Common Pitfalls

  1. Create the schema before the data: Weaviate requires a schema before you can store data. Attempting to insert objects into a non-existent class throws an error. Always define the schema first.

  2. Vector dimensions must be consistent: All vectors in a class must have the same dimension. If you switch embedding models, you must recreate the class and reload the data.

  3. Vectorizer misconfiguration: If you set Configure.Vectorizer.none() but don’t provide vectors, Weaviate stores objects without vectors. Queries then fail. Ensure your vectorizer configuration matches how you’re providing data.

  4. Underestimating GraphQL syntax: GraphQL is powerful but error-prone. A wrong field name or typo in your query produces cryptic errors. Use the Python client, which generates correct syntax for you.

  5. Forgetting persistence volumes: Without a Docker volume, all data vanishes after a restart. Always configure PERSISTENCE_DATA_PATH with a volume.

  6. Resource overhead with modules: Enabling vectorization modules like text2vec-transformers significantly increases RAM and CPU demand. For local setups without GPU, computing vectors externally is often better.

  7. Leaving authentication disabled: Our example enables anonymous access, fine for local testing but never for publicly reachable instances.

  8. Not understanding indexes: Weaviate uses HNSW for vector indexing by default. With very large datasets, familiarize yourself with index parameters to optimize search speed.

Hardware, Costs, and Security

Weaviate without vectorization modules runs lean. A machine with 4 GB RAM and a standard CPU handles a few thousand documents just fine. Once you enable modules like text2vec-transformers, RAM requirements climb to 8 GB or higher, and a GPU significantly speeds up vectorization.

Weaviate is open source and free. The Community Edition includes all the features you need for local RAG projects. A paid cloud version exists, but it’s irrelevant for local deployments.

Security follows the same principle as other local databases: as long as Weaviate stays within your own network, your data stays protected. If you expose Weaviate over the network, enable authentication and run it behind a reverse proxy with TLS. Since everything stays local, you gain a major advantage over cloud-based vector databases, as covered in the article on local AI versus cloud AI.

Further Reading

FAQ

Do I need to learn GraphQL to use Weaviate?

Not necessarily. The Python client abstracts away the GraphQL queries for you. That said, if you need complex queries with filters and relationships, understanding GraphQL basics helps.

Can Weaviate calculate its own vectors?

Yes, using modules like text2vec-transformers or text2vec-cohere. For local setups without a GPU, it’s often more efficient to compute vectors externally and pass them to Weaviate.

Is Weaviate free?

Yes, the open source version is free and covers everything you need for local projects. A paid cloud version exists, but it’s unnecessary for local deployments.

How many documents can Weaviate handle locally?

It depends on RAM and disk space. Weaviate handles hundreds of thousands to millions of objects. For very large datasets, tune your index parameters.

Can I connect Weaviate with Ollama?

Yes. Ollama provides the language model, Weaviate provides the vector database. Your Python script bridges both: Weaviate finds relevant documents, Ollama generates the response.

What’s the difference between Weaviate and Chroma?

Chroma is simpler and faster to set up, ideal for prototypes. Weaviate offers more features like GraphQL, Hybrid Search, and a module system, but requires more setup complexity.

Do I need Docker for Weaviate?

Docker is the recommended approach, though binaries are available. For local testing and production systems, Docker is simplest and best documented.

Does Weaviate support hybrid search?

Yes, Hybrid Search is one of Weaviate’s strengths. You weight vector and keyword search using the alpha parameter and get combined results.

Can I run Weaviate on a NAS?

Yes, with Docker. Make sure you have sufficient RAM and fast storage. Weaviate benefits from SSD storage, especially with large datasets.

How do I secure Weaviate?

Local instances without network exposure are usually safe in secure networks. To access over the network, enable authentication and use a reverse proxy with TLS encryption.

What’s the difference between Weaviate and Qdrant?

Qdrant is leaner and focused on pure vector search. Weaviate offers more features like GraphQL, a module system, and built-in Hybrid Search, but uses slightly more resources.

Sources

  • Weaviate official website: weaviate.io
  • Weaviate documentation: weaviate.io/developers/weaviate
  • Weaviate Python Client: github.com/weaviate/weaviate-python-client
  • Weaviate GitHub repository: github.com/weaviate/weaviate
  • Article on Vector Databases in this series
  • Article on Hybrid Search in this series
Back to Blog
Share:

Related Posts