skip to content

Vector

Stores built for nearest-neighbour search over embeddings rather than exact lookups, which is what makes semantic search and RAG possible. Interviewers use this area to check you understand approximate search — recall traded against latency — and how filtering and hybrid scoring change the picture.

on this pageshow

explore

questions

105 · 6 sections

In Pinecone, what do the dimension and metric arguments to create_index lock in?

level: juniorimportance: must knowfreq 78%
basics
~20 s

create_index fixes an index's vector dimension and distance metric permanently. Every vector you upsert must have exactly that length or the write is rejected, and switching either setting means creating a new index and re-upserting the data.

open as a page

What does a Pinecone vector record contain, and how should you batch upserts?

level: juniorimportance: must knowfreq 82%
basics
~20 s

A Pinecone record is an id string, a values list whose length must equal the index dimension, and optional metadata. index.upsert() takes a list of records, so send batches of roughly 100 to stay under the request size cap.

open as a page

Why must a Pinecone index use the dotproduct metric for hybrid sparse-dense search?

level: middleimportance: must knowfreq 62%
basics
~20 s

Pinecone accepts sparse values only in indexes created with metric="dotproduct". Dot product is linear, so scaling the dense and sparse query vectors weights their contributions predictably; cosine and euclidean indexes reject sparse vectors, and the metric cannot be changed later.

open as a page

In Pinecone, how do you upsert and query a record holding both dense and sparse vectors?

level: middleimportance: must knowfreq 55%
basics
~20 s

A hybrid record carries the dense embedding in values and a sparse vector in sparse_values as {"indices": [...], "values": [...]}. The query passes vector= and sparse_vector= together, and Pinecone returns one ranked list with a single combined score per match.

open as a page

What is a Pinecone namespace, and how does it change query behaviour?

level: middleimportance: must knowfreq 70%
basics
~20 s

A namespace is a logical partition inside a Pinecone index. Each upsert and each query names one namespace, and a query searches only that partition — there is no cross-namespace search in a single call. Namespaces are created implicitly on first write.

open as a page

In Weaviate, what is a collection and what does collections.create define?

level: juniorimportance: must knowfreq 70%
basics
~20 s

A collection is Weaviate's typed container for objects of one kind, much like a table. collections.create names it and declares its properties with data types, plus per-collection settings such as the vector index, replication and multi-tenancy.

open as a page

In Weaviate's hybrid() query, what does the alpha parameter control?

level: juniorimportance: must knowfreq 78%
basics
~20 s

alpha weights the two halves of a Weaviate hybrid search: alpha=0 is pure BM25 keyword search, alpha=1 is pure vector search, and values in between blend them. The v4 Python client's default of 0.7 leans toward the vector side.

open as a page

In Weaviate, when do you use near_text, near_vector, or near_object?

level: juniorimportance: must knowfreq 74%
basics
~10 s

near_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.

open as a page

In Weaviate, what does setting a text2vec vectorizer on a collection do?

level: juniorimportance: must knowfreq 72%
basics
~20 s

A configured vectorizer makes Weaviate call the embedding model itself: you insert plain properties and the server produces the vector, and a text query is embedded server-side too. Without one you must supply every vector yourself.

open as a page

Why is relying on Weaviate's auto-schema risky for a production collection?

level: middleimportance: must knowfreq 62%
basics
~20 s

Auto-schema is on by default and invents property definitions from whatever object arrives first, so types are guessed from one sample, stray keys become permanent indexed properties, and the resulting schema differs between environments. Property types cannot be changed afterwards.

open as a page

What are the parts of a Qdrant point, and which id types does it accept?

level: juniorimportance: must knowfreq 80%
basics
~20 s

A Qdrant point is the unit of storage: an id, one or more vectors, and an arbitrary JSON payload. Ids must be an unsigned integer or a UUID — arbitrary strings are rejected. Upserting an existing id replaces that point.

open as a page

In Qdrant, how do you restrict a vector search to points matching a payload condition?

level: juniorimportance: must knowfreq 80%
basics
~10 s

Pass a filter to the search call. In the Python client that is query_points(..., query_filter=models.Filter(must=[models.FieldCondition(key="lang", match=models.MatchValue(value="en"))])). Only points whose payload satisfies the filter come back, still ranked by vector distance.

open as a page

In Qdrant, what do VectorParams size and distance fix at collection creation?

level: middleimportance: must knowfreq 78%
basics
~20 s

VectorParams pins a Qdrant collection's vector dimension and its distance metric for the collection's lifetime. Every upserted point must match that size exactly, and neither value can be changed later — switching embedding models means creating a new collection.

open as a page

In Qdrant, what do hnsw_config's m and ef_construct control, and what do they cost?

level: middleimportance: must knowfreq 72%
basics
~20 s

m is how many graph links Qdrant keeps per vector (default 16); ef_construct is how wide the neighbour search is while building (default 100). Raising m costs RAM permanently, raising ef_construct costs indexing time only.

open as a page

How do must, should, and must_not combine inside a Qdrant Filter?

level: middleimportance: must knowfreq 70%
basics
~20 s

Clauses are ANDed with each other: a point must satisfy every condition in must, at least one in should, and none in must_not. min_should raises the should bar from one to N. Nesting Filter objects inside should expresses OR-of-ANDs.

open as a page

In Chroma, what happens to raw text passed to collection.add(documents=...)?

level: juniorimportance: must knowfreq 76%
basics
~20 s

Chroma runs each document through the collection's embedding function and stores the resulting vector next to the text, its id and its metadata. ids are required and must be unique; documents, metadatas and embeddings are parallel lists.

open as a page

In Chroma, what is the difference between EphemeralClient and PersistentClient?

level: juniorimportance: must knowfreq 80%
basics
~20 s

EphemeralClient keeps collections in memory only and loses everything when the process exits. PersistentClient(path="./chroma") writes to that directory and reloads it on the next run. Plain chromadb.Client() is ephemeral, which is why prototype data disappears.

open as a page

In Chroma, when do you pass query_embeddings instead of query_texts to collection.query()?

level: juniorimportance: must knowfreq 78%
basics
~20 s

query_texts hands raw strings to Chroma, which embeds them with the collection's embedding function. query_embeddings takes vectors you already computed, so Chroma skips embedding entirely. Use it when the vector comes from elsewhere or is cached.

open as a page

Why must a Chroma collection keep the same embedding_function for its whole life?

level: middleimportance: must knowfreq 68%
basics
~20 s

Distances are only meaningful between vectors from the same model. Mixing embedding functions in one Chroma collection puts incomparable vectors in one index, so nearest-neighbour results become arbitrary — and if the dimensions happen to match, nothing errors.

open as a page

In Chroma's query(), how do the where and where_document filters differ?

level: middleimportance: must knowfreq 72%
basics
~20 s

where filters on the structured metadata dictionary attached to each record, using operators like $eq, $in and $gte. where_document filters on the stored document text itself, with $contains and $not_contains substring matching. They are separate arguments and combine with AND.

open as a page

In FAISS, what does IndexFlatL2 do and when is it the right index?

level: juniorimportance: must knowfreq 78%
basics
~20 s

IndexFlatL2 stores every vector uncompressed and compares a query against all of them, returning exact L2 nearest neighbours with no training step. It is the right choice for small collections and as a recall baseline, but its cost grows linearly with the dataset.

open as a page

How do you move a FAISS index onto a GPU, and what does StandardGpuResources do?

level: middleimportance: must knowfreq 62%
basics
~20 s

Create a faiss.StandardGpuResources() object, then call faiss.index_cpu_to_gpu(res, device, index). The resources object owns the GPU scratch memory and cuBLAS handles for that device, and you must keep a Python reference to it for as long as the index lives.

open as a page

What does the FAISS index_factory string "IVF4096,PQ64" build?

level: middleimportance: must knowfreq 70%
basics
~20 s

It builds an IVFPQ index: a coarse quantizer that splits the space into 4096 inverted lists, with each vector stored as a product-quantized code of 64 one-byte values instead of the raw floats. Both stages must be trained before adding data.

open as a page

Why must a FAISS IVF index be trained before add(), and on what data?

level: middleimportance: must knowfreq 76%
basics
~20 s

IVF and PQ indexes learn structure from data — k-means centroids for IVF, codebooks for PQ. Until train() runs, is_trained is False and add() raises. Train on a representative sample of the vectors you will actually search.

open as a page

When do you shard a FAISS index across GPUs instead of replicating it?

level: seniorimportance: must knowfreq 52%
basics
~20 s

Replicate when the index fits on one GPU and you need more queries per second — each device holds a full copy and queries are split between them. Shard when the index does not fit on one GPU: each device holds a slice, every query touches all of them, and results are merged.

open as a page

In LanceDB, how do you run a vector search and read the results as a DataFrame?

level: juniorimportance: must knowfreq 62%
basics
~20 s

Call table.search(query_vector), chain .limit(n) to say how many neighbours you want, and finish with .to_pandas(). Every returned row carries the table's own columns plus a _distance column holding that row's distance from the query vector.

open as a page

In LanceDB, how do you create a table and where can its schema come from?

level: juniorimportance: must knowfreq 72%
basics
~20 s

db.create_table(name, data=...) infers an Arrow schema from a pandas DataFrame, PyArrow table or list of dicts. Passing schema= with a PyArrow schema or a lancedb.pydantic LanceModel defines it explicitly and allows creating an empty table.

open as a page

In LanceDB's create_index, what do num_partitions and num_sub_vectors control?

level: middleimportance: must knowfreq 58%
basics
~20 s

num_partitions sets how many clusters the vectors are split into, so it governs how much data one query touches per probe. num_sub_vectors sets how many pieces each vector is chopped into for compression, so it governs index size and how lossy stored distances are.

open as a page

What does LanceDB do when you search a table with no vector index?

level: middleimportance: must knowfreq 68%
basics
~20 s

It runs an exhaustive brute-force scan, comparing the query against every vector in the table. Results are exact, but latency grows linearly with row count. Calling create_index builds an approximate IVF_PQ index that trades that exactness for sub-linear search.

open as a page

How does LanceDB versioning work, and how do you read an older table version?

level: middleimportance: must knowfreq 65%
basics
~20 s

Every write to a LanceDB table — append, update, delete, overwrite, index build — commits a new immutable version instead of mutating data in place. table.list_versions() enumerates them, table.checkout(n) pins the table object to version n for reading, and table.checkout_latest() returns to the newest.

open as a page