In Weaviate, when do you use near_text, near_vector, or near_object?
answer
- three ways to get one query vector
- who computes the embedding?
- server-side vectorizer versus your own floats
- UUID as the query input
- same model, same dimensions, or garbage
basics
~10 snear_text sends a raw string and lets the collection's configured vectorizer embed it server-side. near_vector takes an embedding you computed yourself. near_object finds the neighbours of an object already stored, referenced by its UUID.
solid answer
~40 sAll three are nearest-neighbour searches on the same collection; they differ only in where the query vector comes from. - `collection.query.near_text(query="...")` hands a string to the server, which embeds it with the vectorizer configured on the collection. If the collection has no vectorizer, this call fails — there is nothing to turn the string into a vector. - `collection.query.near_vector(near_vector=[...])` takes a list of floats you produced yourself. This is the bring-your-own-embeddings path and works regardless of vectorizer config, but you must use the *same* model and dimensionality that produced the stored vectors. - `collection.query.near_object(near_object=uuid)` reuses the vector of an object already in the collection, which is how you build "more like this" without re-embedding anything. All three accept the same result-shaping arguments: `limit`, `filters`, `return_metadata`, `return_properties`, `auto_limit`, `offset`.
code
python · 22 linesfrom weaviate.classes.query import MetadataQuery
articles = client.collections.get("Article")
# 1. server embeds the string using the collection's vectorizer
a = articles.query.near_text(
query="electric guitars",
limit=5,
return_metadata=MetadataQuery(distance=True),
)
# 2. you supply the embedding yourself
b = articles.query.near_vector(
near_vector=[0.12, -0.03, 0.55],
limit=5,
)
# 3. reuse the vector of an object already stored
c = articles.query.near_object(
near_object="7f0a1c2e-1234-4c1a-9e2b-8f6d5a4b3c21",
limit=5,
)go deeper
Be able to say plainly which method takes a string, which takes a list of floats, and which takes a UUID, and that only the string form needs a vectorizer on the collection.
Explain that all three converge on one nearest-neighbour search once the query vector exists, and that limit, filters and metadata options are shared across them.
Show judgment about where embedding should happen: keeping the database off the embedding provider's network on the query path, guaranteeing model parity between ingest and query, and using stored vectors instead of re-embedding.
Own the consequence of the choice at organisation scale — server-side vectorization couples the database to a model version and a provider, while client-side embedding moves that coupling into your pipeline and makes a model migration a re-index project you must plan for.
## The one idea behind all three A vector search needs exactly two things: a query vector and a collection to search. Weaviate exposes three query methods that differ *only* in how the query vector is obtained. Once the vector exists, the search path, the filtering, and the result shaping are identical. Understanding that collapses what looks like three APIs into one API with three front doors. ## near_text — the server embeds for you ```python response = collection.query.near_text(query="electric guitars", limit=5) ``` Weaviate takes the string, calls the vectorizer that was configured on the collection when it was created, gets back an embedding, and searches with it. This is the convenience path: you never touch an embedding model in your application code, and query-time and ingest-time embedding are guaranteed to use the same model because they are the same server-side configuration. The hard requirement is that the collection actually has a vectorizer. A collection created with no vectorizer stores only the vectors you supply, and `near_text` on it returns a server error saying no vectorizer is configured. This is the single most common first-day surprise with Weaviate. `near_text` also accepts `move_to` and `move_away` with `Move(force=..., concepts=[...])`, which nudge the query vector toward or away from extra concepts before the search runs — an option the other two front doors do not have, because they do not build the vector from text. ## near_vector — you embed ```python vec = my_model.encode("electric guitars") response = collection.query.near_vector(near_vector=vec, limit=5) ``` This is the explicit path. You own the embedding model, so you own the failure mode: the query vector must come from the same model, the same version, and the same dimensionality as the vectors stored in the collection. Mixing models silently produces garbage rankings rather than an error — the numbers are still floats of the right length, they just live in a different space. Dimension mismatches, by contrast, do fail loudly, because the collection's vector index has a fixed dimensionality. Use `near_vector` when embedding happens elsewhere in your pipeline (a batch job, a shared embedding service, a model you fine-tuned), when you want to search with a vector that is not the embedding of any text at all — an averaged user-preference vector, an image embedding, an arithmetic combination — or when you simply do not want the database making outbound calls to an embedding provider on the query path. ## near_object — reuse a stored vector ```python response = collection.query.near_object(near_object=some_uuid, limit=5) ``` Here the query vector is the vector Weaviate already holds for that object. No embedding call happens at all, which makes this the cheapest of the three. It is the natural implementation of "related articles", "similar products", or "more like this" on a detail page: you already know the UUID of the thing the user is looking at. One detail worth knowing: the source object itself is a perfect match for its own vector, so it normally comes back first. Either request `limit` + 1 and drop it client-side, or exclude it with a filter on its id. ## What they share Because the difference ends once the query vector exists, every result-shaping argument is common to all three: - `limit` and `offset` for how many results and where to start - `filters` for structured constraints, applied against the collection's inverted index - `distance` or `certainty` for a similarity cutoff - `auto_limit` for cutting the list where similarity drops off - `return_metadata=MetadataQuery(distance=True)` to see how close each hit actually was - `return_properties=[...]` to keep the payload small - `group_by` to fold results into groups A useful mental exercise before an interview: write the same search three ways and notice that only the first argument changes. ## Choosing in practice Reach for `near_text` when the collection is vectorized by the server and your query genuinely is text — it is the shortest correct code. Reach for `near_vector` when you control embeddings, when the query is not text, or when you need to keep the database off the network. Reach for `near_object` whenever the reference point is a row you already have, because re-embedding its text to search for its neighbours is pure waste and can even drift if the model changed since ingest.
- You call near_text on a collection that stores only vectors you uploaded yourself. What happens?The query fails. Weaviate has no way to turn the string into a vector because the collection has no vectorizer configured, so the server rejects the request rather than guessing a model. Either configure a vectorizer on the collection or embed the text in your application and use near_vector instead.
- With near_object, why does the first result usually look useless?Because the query vector is the stored object's own vector, that object is at distance zero from itself and ranks first. Ask for one more result than you need and drop it, or add a filter excluding that id, before showing "related items" to a user.
- What breaks if your application switches embedding models but keeps using near_vector against an existing collection?Nothing errors as long as the dimensionality matches, which is what makes it dangerous. The query vector lands in a different geometric space from the stored vectors, so rankings become effectively random while every call still returns results. Re-embedding the whole collection is the only real fix.
saying these in an interview costs you the question
- Thinking near_text works on any collection regardless of vectorizer
- Assuming near_vector re-embeds the numbers you pass in
- Believing near_object takes an object's text rather than its UUID
- Mixing embedding models between ingest and near_vector queries
- Claiming the three methods search different indexes