gRPC API
polign_db serves the same operations over gRPC (default
localhost:23001) and HTTP at once. Same database, two wire formats. The service
definition below is the wire contract; the shipped clients speak it for you.
The service
service VectorDB { rpc PutVector(PutVectorRequest) returns (PutVectorResponse); rpc PutVectors(PutVectorsRequest) returns (PutVectorsResponse); rpc GetVector(GetVectorRequest) returns (GetVectorResponse); rpc GetVectors(GetVectorsRequest) returns (GetVectorsResponse); rpc ListVectors(ListVectorsRequest) returns (ListVectorsResponse); rpc DeleteVector(DeleteVectorRequest) returns (DeleteVectorResponse); rpc SearchVectors(SearchVectorsRequest) returns (SearchVectorsResponse); // Collection admin โ only for servers running the collections registry // (-byo-store); returns Unimplemented otherwise rpc CreateCollection(CreateCollectionRequest) returns (CreateCollectionResponse); rpc GetCollection(GetCollectionRequest) returns (GetCollectionResponse); rpc ListCollections(ListCollectionsRequest) returns (ListCollectionsResponse); rpc DeleteCollection(DeleteCollectionRequest) returns (DeleteCollectionResponse); rpc VerifyCollection(VerifyCollectionRequest) returns (VerifyCollectionResponse); }
For everyday use you only need the first seven: collections are auto-created on the first
PutVector, inferring their dimension from that vector, so most setups never make
an explicit "create collection" call. The five collection-admin RPCs exist for servers that
manage collections on customer-owned buckets (started with -byo-store). On any
other server they return UNIMPLEMENTED. PutVectors is the batch
upsert: up to 5000 vectors per call, validated as a whole before anything is applied (an
invalid batch writes nothing); chunk larger loads. GetVectors is its read-side
twin, fetching many vectors by id in one call; unlike GetVector, its values
come back byte-exact (never a compressed reconstruction).
Typed metadata
Metadata values are typed scalars (server v0.3.0+). The wire carries them in a
TypedValue message:
message TypedValue { oneof value { string str = 1; double number = 2; bool boolean = 3; } }
Vector.typed_metadata (field 4) and SearchHit.typed_metadata
(field 5) are additive: the legacy map<string, string> metadata field is
always served with every value's canonical string form, and the typed map is filled only
when a record actually holds a non-string value, so pre-0.3.0 clients are untouched. On
writes, typed_metadata wins over metadata when both are set.
There is no request-side typed opt-in on gRPC (unlike HTTP's ?typed=true);
the server always sends both fields, and a client simply reads the one it wants โ the
Python GrpcClient's typed_metadata=True does exactly that. One
round-trip caveat: gRPC carries numbers as doubles, so a source literal like
0.50 reads back as 0.5 (HTTP JSON preserves the literal).
Python client
The Python SDK's GrpcClient (the
[grpc] extra) ships pre-generated stubs for this API and maps status codes to
the same typed exceptions as its HTTP client. The operations are identical, so you just swap one class:
# pip install "polign[grpc]" from polign import GrpcClient client = GrpcClient("localhost:23001") # Store an embedding (collection auto-created from the first vector's dimension) client.put("docs", "doc-1", embedding, metadata={"title": "Cats"}) # Nearest-neighbour search; filters, hybrid text search, and batching # work exactly as in the HTTP client for hit in client.search("docs", values=query_embedding, k=10): print(hit.id, hit.distance, hit.metadata)
Go has a native gRPC client, importable as
github.com/Polign/polign_db/client. Other languages can generate stubs from
the proto, or talk to the HTTP API: the same operations over
JSON, no stubs needed.
SearchVectors options
| Field | What it does |
|---|---|
values | The query embedding. Omit it (and set text) for a pure BM25 search. |
k | How many hits to return. |
ef | Search beam width override; 0 = server default. Larger = more accurate, slower. |
filter | Legacy metadata equality filter, AND across keys, which is exactly an AND of eq conditions. Applied in-graph on both the in-memory and cold paths. |
filter_expr | Typed filter expression tree: eq/in/range/exists conditions composed with and/or/not. range bounds are strings and compare lexicographically unless the range's numeric flag is set, which parses them as doubles. Setting both filter and filter_expr is an error. The Python client builds it from its filter dict. |
cold | Serve straight from object-storage segments instead of the in-memory index. Requires a segment store. |
nprobe | IVF probe-count override for cold queries; 0 = searcher default. |
text | BM25 query. Alone = text search; together with values = hybrid. |
fusion | Hybrid fusion: method = "rrf" (default, rrf_k=60) or "linear" (alpha = vector-leg weight, default 0.5). Only valid when both legs are present. |
rescore | Accuracy/speed dial for compressed (IVF-PQ) collections: 0 = server default (accuracy-first), > 0 = exact-rescore pool of that size, < 0 = fastest approximate ranking with no exact rescore. Other collection types ignore it. |
ListVectorsRequest takes the same filter_expr to restrict a
listing by metadata; offset and the returned total then count
matching records only, so a filtered listing pages exactly like an unfiltered one.
Each SearchHit carries a distance (vector metric,
smaller-is-closer), a score (relevance, larger-is-better: BM25 on a text
search, the fused score on a hybrid one, 0 on a pure vector search), and the
hit's metadata (both the string map and, when typed values exist, typed_metadata).
Text and hybrid search read the object-store segment index, so they need the server started
with -segment-stores and a persistor running. See the
install & use guide.
Errors
| gRPC code | Meaning |
|---|---|
NOT_FOUND | Missing vector or collection on GetVector. |
INVALID_ARGUMENT | Bad request, including a query whose dimension doesn't match the collection's. |
FAILED_PRECONDITION | On data-plane RPCs with placement enabled: this node doesn't own the resource; the message names the owner to redial. On collection-admin RPCs: the collection is still pending verification. |
ALREADY_EXISTS | CreateCollection on a collection that is already registered. |
UNIMPLEMENTED | A collection-admin RPC on a server that isn't running the collections registry (-byo-store), or listing a cold-served resource this node keeps no in-memory index for. |
UNAUTHENTICATED / PERMISSION_DENIED | Missing or wrong API key on a collection-admin RPC (only those calls require a key). |
RESOURCE_EXHAUSTED | Rate limit hit (servers started with -rate-limit), or write backpressure when the unpersisted tail overlay is at its cap. |
UNAVAILABLE | Server unreachable or connection lost. |
INTERNAL | Anything else. |
This page is the gRPC wire API of polign_db. The same operations are also available over HTTP/JSON, from the command line or with the curl examples in the HTTP API reference.