Collections
Collections are the object stores where your data lives. Every object you upsert belongs to a collection. A collection declares a set of named, typed fields. Each object then carries values for any subset of those fields.
Field Types
A collection is created from a list of field definitions. Endee supports three field types, which you can freely combine in one collection:
| Type | Purpose | Required keys | params |
|---|---|---|---|
vector | Dense semantic search (one vector per object) | name, type | dimension, space_type, precision (+ optional M, ef_con) |
sparse | Keyword / BM25 search | name, type, sparse_model | — (no params) |
multi_vector | Many vectors per object, pooled for retrieval (e.g. ColBERT) | name, type | dimension, space_type, precision, pooling ("mean"/"max") (+ optional M, ef_con) |
Dense Collections
A dense vector field enables semantic search: finding items based on meaning rather than exact keyword matches. Each object’s value is a list of numbers, one per dimension, representing the meaning of your content.
Use a dense field when you want to:
- Find semantically similar documents
- Power recommendation systems
- Enable image/video similarity search
Python
from endee import Endee
client = Endee("your-serverless-token")
client.create_collection(
name="my_collection",
fields=[
{
"name": "embedding",
"type": "vector",
"params": {"dimension": 384, "space_type": "cosine", "precision": "int16"},
},
],
)Hybrid Collections
Add a sparse field alongside a dense vector field to combine semantic similarity with keyword matching (BM25). You query both fields and fuse the results, giving you the best of both worlds: meaning and exact terms.
Use a hybrid collection for:
- Document retrieval in RAG pipelines
- Search where both meaning and keywords matter
- Any use case where dense-only search misses exact terminology
Python
client.create_collection(
name="hybrid_collection",
fields=[
{
"name": "embedding",
"type": "vector",
"params": {"dimension": 384, "space_type": "cosine", "precision": "int16"},
},
{"name": "keywords", "type": "sparse", "sparse_model": "endee_bm25"},
],
)See the Sparse Vectors (BM25) guide for installing endee-model and generating BM25 embeddings.
Sparse Model Options:
sparse_model | Description |
|---|---|
default | Bring your own sparse vectors (you provide final indices and values). Use for SPLADE or any custom model. |
endee_bm25 | Use Endee’s BM25 model via the endee-model package. Endee holds the IDF weights server-side and applies them automatically, so you only send TF weights. |
The sparse_model parameter
sparse_model="endee_bm25": use this when your sparse vectors come fromendee/bm25. Endee holds the IDF weights on its server and applies them automatically, so you only need to send the TF weights from your client.sparse_model="default": use this for SPLADE models or any other BM25 model. Endee treats the values you send as final scores and does no further calculation. If you use a different BM25 model (notendee/bm25), compute the full IDF scores yourself on the client before sending them.
Multi-Vector Collections
A multi_vector field stores several vectors per object (for example, one per token or passage) and pools them into a single vector for retrieval. Two pooling strategies are supported:
mean: elementwise average of the membersmax: elementwise maximum of the members
Python
client.create_collection(
name="passages",
fields=[
{
"name": "embedding",
"type": "vector",
"params": {"dimension": 384, "space_type": "cosine", "precision": "int8"},
},
{
"name": "colbert",
"type": "multi_vector",
"params": {"dimension": 384, "space_type": "cosine", "precision": "int8", "pooling": "mean"},
},
],
)Field Parameters
For vector and multi_vector fields, the params object configures dimensionality, distance, quantization, and HNSW build behavior:
| Parameter | Description | Default |
|---|---|---|
dimension | Dense vector dimensionality (max 10,000) | Required |
space_type | Distance metric: cosine, l2, or ip (inner product) | cosine |
precision | Vector quantization level (see Precision) | int8 |
pooling | Pooling strategy for multi_vector fields: mean or max | Required (multi-vector) |
M | HNSW graph connectivity (higher = better recall, more memory) | 16 |
ef_con | HNSW build-time quality parameter (higher = better quality, slower build) | 128 |
Python
# All vector params explicitly set
client.create_collection(
name="my_collection",
fields=[
{
"name": "embedding",
"type": "vector",
"params": {
"dimension": 768,
"space_type": "cosine",
"precision": "float32",
"M": 32, # higher connectivity = better recall, more memory
"ef_con": 200, # higher = better index quality, slower build
},
},
],
)Distance Metrics
Choose the appropriate distance metric based on your embedding model and use case:
| Metric | Value | Description | Best For |
|---|---|---|---|
| Cosine | cosine | Measures the angle between vectors (direction only) | Text embeddings, normalized vectors |
| L2 | l2 | Euclidean distance (magnitude and direction) | Image embeddings, spatial data |
| Inner Product | ip | Dot product similarity | Maximum inner product search (e.g., recommendation) |
Most embedding models (e.g., Sentence Transformers, OpenAI) produce normalized embeddings. Use cosine by default. Endee L2-normalizes cosine vectors client-side before sending.
HNSW Algorithm
Dense and multi-vector fields use the HNSW (Hierarchical Navigable Small World) algorithm for Approximate Nearest Neighbor (ANN) search. The two build-time parameters (M and ef_con) control the quality vs. memory/build-time trade-off.
| Parameter | Effect of Increasing |
|---|---|
M | Higher recall, more memory usage |
ef_con | Better index quality, slower build time |
The defaults (M=16, ef_con=128) are good starting points for most workloads.
ef_con is a build-time parameter set when creating the collection; it controls index quality and cannot be changed without rebuilding the field. ef_search is a separate query-time parameter that controls how many candidates are explored per search. The two are independent. See Search: Search Parameters.
Collection Management
List Collections
Python
collections = client.list_collections()
for col in collections:
print(col)Get Collection
Returns a handle to an existing collection for searching and upserting.
Python
collection = client.get_collection("my_collection")Describe Collection
Returns the collection’s field definitions and metadata.
Python
info = collection.describe() # {name, fields, created_at, layout_version}Delete Collection
Deletion is irreversible. All objects in the collection are permanently removed.
Python
client.delete_collection("my_collection")Collection Maintenance
Rebuild
Rebuild one or more dense vector fields’ HNSW graphs to apply new M / ef_con values. Rebuild runs asynchronously. See Rebuild for the full API, polling pattern, and status response shape.
Shrink
Defragment the collection’s storage in place.
Python
collection.shrink() # {"status": "ok", "reclaimed_bytes": <int>}