Weaviate Essentials
Theme
Palette
Download
Caption (tap to copy)
📖 Deep dive (full written explanation)
This cover frames the whole day. The single most useful mental model for Weaviate is that it unifies two things most stacks keep separate: the data object and its meaning. In a typical setup you have a document store (Postgres, Elastic) and, bolted on, a vector index. Weaviate collapses that into one system where the object, its metadata, and its embedding are one logical unit.
The rest of this post builds that model deliberately: what Weaviate is, how it differs from a raw approximate-nearest-neighbor library, the schema concepts of collections and objects, the module system that can generate embeddings for you, and the situations where Weaviate is genuinely the right tool.
The precise definition matters because 'vector database' is an overloaded term. Some products are thin wrappers over an ANN index; Weaviate is a full database. It persists data to disk, enforces a schema, supports CRUD, offers filtering, replication, and multi-tenancy, and exposes query APIs over REST, GraphQL, and gRPC.
The defining capability is searching by semantic similarity: you compare the query's embedding to stored embeddings and return the closest objects. But because it is a real database, you can combine that with keyword search and structured filters in a single query, which is what separates it from a bare index.
This comparison is the most common point of confusion. Libraries like FAISS and HNSWlib are excellent at one job: indexing vectors and returning nearest neighbors. They do not store your original objects, they don't persist across restarts on their own, they have no schema, no metadata filtering, and no API beyond function calls in your process.
Weaviate sits a level up. It owns the storage of objects and metadata, manages the lifecycle of the vector index for you, exposes network APIs, and — crucially — can generate the embeddings itself via modules. If you only need an in-process index inside one Python service, a library may be enough. If you need a shared, persistent, queryable service, you want a database.
Collections (called classes in older versions and docs) are Weaviate's equivalent of tables. A collection defines a schema: a set of named, typed properties. Types include text, int, number, boolean, date, uuid, geoCoordinates, and references to other collections.
This schema does real work. The property types determine how data is indexed for filtering and keyword search, and the collection's configuration decides which vectorizer module runs and which distance metric the vector index uses. Designing the collection well up front — what to make filterable, what to vectorize — directly shapes query performance later.
The key insight is co-location. Each object carries its human-readable properties and its machine-readable vector(s) together. The properties feed BM25 keyword search and the inverted index used for filtering; the vector feeds the HNSW similarity index. Because both indexes point at the same object IDs, a single request can filter on a property and rank by vector similarity at once.
Weaviate also supports named vectors: one object can hold several embeddings (for example a title vector and a body vector), each with its own index and configuration. That lets you search different facets of the same object independently.
Modules are Weaviate's plug-in system, and the vectorizer module is the one you meet first. With text2vec-openai, text2vec-cohere, text2vec-transformers, or others configured, Weaviate calls that model automatically when you import an object and again when you run a near_text query — so you never manually manage embeddings.
If you prefer to generate vectors yourself (your own model, a batch pipeline, or for cost control), set the vectorizer to none and supply vectors explicitly on import and at query time with near_vector. Other module families add reranking and generative (RAG) capabilities, but the vectorizer is the foundational one.
This diagram makes the 'object is one unit' idea concrete. At the top is the collection schema, which configures both the typed properties and the vectorizer. Below it, each stored object holds its property values. Alongside those values lives the vector embedding — for OpenAI's small model, 1536 floats. Finally, an entry in the HNSW graph points back to that object so similarity search can find it.
Reading it top to bottom shows the path data takes at import: schema validates the object, the vectorizer produces the embedding, and the index records a pointer. Reading bottom to top shows the query path: the graph finds candidates, which resolve to objects, whose properties you return.
These built-in capabilities are why teams choose a database over a library. You get three query interfaces — GraphQL for expressive nested queries, REST for simple operations, and gRPC for high-throughput, low-latency access used by the modern clients. You get three search modes — pure vector, BM25 keyword, and hybrid fusion.
Metadata filtering composes with vector search via pre-filtering, so 'find items similar to X where price < 50 and inStock = true' is one call. And the module ecosystem means reranking and even LLM generation (retrieval-augmented generation) can run inside the database, close to the data.
This is the minimum viable connection. After running Weaviate locally (typically via Docker Compose), the v4 Python client's connect_to_local() helper handles host, ports, and gRPC setup for you. is_ready() confirms the server is up and reachable.
Note the explicit client.close() at the end. The v4 client holds gRPC connections open, and leaking them across many short scripts or request handlers causes resource warnings and eventual exhaustion. In long-running services, create one client and reuse it; in scripts, close it or use it as a context manager. For Weaviate Cloud you would instead use connect_to_weaviate_cloud() with a URL and API key.
These are the situations where Weaviate clearly fits. Semantic search over a corpus — documentation, products, support tickets, legal text — is the classic case, because users phrase queries differently from how content is written. RAG backends are the fastest-growing case: the LLM needs the most relevant chunks, filtered by tenant or recency, and that is exactly vector-plus-filter retrieval.
It's also the right pick when you'd rather not run a separate embedding pipeline; the vectorizer module folds that into the database. And the deciding factor against a library is whether you need a real, shared, persistent service with CRUD and a network API — if so, the database wins.
This flow shows where Weaviate lives relative to your application. Raw data — documents, product records — flows into Weaviate, which embeds, stores, and indexes it in one step. At query time your application sends a vector or hybrid query and Weaviate returns ranked objects. Those results either go straight back to the user as search results, or feed an LLM as retrieved context in a RAG pipeline.
The takeaway is that Weaviate is infrastructure that sits between your data and your application or model. It is not the user-facing app and not the model itself; it is the retrieval layer that makes both faster and smarter.
The teaser points to Day 88. Having established what Weaviate is, the natural next question is why semantic search is worth the added infrastructure at all — which is exactly what the next post (Why It Matters) tackles, contrasting keyword and meaning-based retrieval.