Skip to Content
v2ConceptsCollections

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:

TypePurposeRequired keysparams
vectorDense semantic search (one vector per object)name, typedimension, space_type, precision (+ optional M, ef_con)
sparseKeyword / BM25 searchname, type, sparse_model— (no params)
multi_vectorMany vectors per object, pooled for retrieval (e.g. ColBERT)name, typedimension, 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
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
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_modelDescription
defaultBring your own sparse vectors (you provide final indices and values). Use for SPLADE or any custom model.
endee_bm25Use 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 from endee/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 (not endee/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 members
  • max: elementwise maximum of the members
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:

ParameterDescriptionDefault
dimensionDense vector dimensionality (max 10,000)Required
space_typeDistance metric: cosine, l2, or ip (inner product)cosine
precisionVector quantization level (see Precision)int8
poolingPooling strategy for multi_vector fields: mean or maxRequired (multi-vector)
MHNSW graph connectivity (higher = better recall, more memory)16
ef_conHNSW build-time quality parameter (higher = better quality, slower build)128
# 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:

MetricValueDescriptionBest For
CosinecosineMeasures the angle between vectors (direction only)Text embeddings, normalized vectors
L2l2Euclidean distance (magnitude and direction)Image embeddings, spatial data
Inner ProductipDot product similarityMaximum 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.

ParameterEffect of Increasing
MHigher recall, more memory usage
ef_conBetter 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

collections = client.list_collections() for col in collections: print(col)

Get Collection

Returns a handle to an existing collection for searching and upserting.

collection = client.get_collection("my_collection")

Describe Collection

Returns the collection’s field definitions and metadata.

info = collection.describe() # {name, fields, created_at, layout_version}

Delete Collection

Deletion is irreversible. All objects in the collection are permanently removed.

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.

collection.shrink() # {"status": "ok", "reclaimed_bytes": <int>}