Vectors
Vectors are the fundamental data units stored in an index. Each vector has a unique ID, an embedding array, and optional metadata and filter fields.
Dense Vector Fields
| Field | Required | Description |
|---|---|---|
| ID | Yes | Unique string identifier for the vector |
| Vector | Yes | Dense embedding array (must match the index dimension) |
| Meta | No | Arbitrary metadata object — returned in query results |
| Filter | No | Key-value pairs used to filter results during queries |
Python
index = client.get_index(name="my_index")
index.upsert([
{
"id": "doc1",
"vector": [0.12, -0.34, 0.89, ...],
"meta": {"title": "Introduction to ML"},
"filter": {"category": "tech", "year": 2024}
},
{
"id": "doc2",
"vector": [0.55, 0.21, -0.10, ...],
"meta": {"title": "Deep Learning Basics"},
"filter": {"category": "tech", "year": 2023}
}
])Hybrid Vector Fields
For hybrid indexes, include sparse vector components alongside the dense vector:
| Field | Required | Description |
|---|---|---|
| Sparse Indices | Yes | Non-zero term positions in the sparse vector |
| Sparse Values | Yes | BM25 weights corresponding to each index position |
Python
index.upsert([
{
"id": "doc1",
"vector": [0.12, -0.34, 0.89, ...],
"sparse_indices": [4821, 19043, 73201],
"sparse_values": [1.42, 0.87, 1.15],
"meta": {"title": "Introduction to ML"}
}
])sparse_indices and sparse_values must have the same length. Each position in sparse_indices maps to the weight at the same position in sparse_values.
Maximum batch size is 1,000 vectors per upsert call.
Precision
The precision parameter controls how vectors are stored internally. Lower precision reduces memory and speeds up search at the cost of some accuracy.
| Precision | Bits | Storage | Speed | Accuracy |
|---|---|---|---|---|
| BINARY | 1-bit | Smallest | Fastest | Lower |
| INT8 | 8-bit | Small | Fast | Good |
| INT16 | 16-bit integer | Medium | Medium | Higher |
| FLOAT16 | 16-bit float | Medium | Medium | High |
| FLOAT32 | 32-bit float | Largest | Slower | Highest |
Python
from endee import Precision
# INT8 — recommended for most use cases
client.create_index(name="my_index", dimension=384,
space_type="cosine", precision=Precision.INT8)
# FLOAT32 — maximum accuracy
client.create_index(name="precise_index", dimension=384,
space_type="cosine", precision=Precision.FLOAT32)
# BINARY — minimum memory
client.create_index(name="large_index", dimension=384,
space_type="cosine", precision=Precision.BINARY)Recommendations:
- INT8 — best balance of speed, memory, and accuracy for most use cases (default)
- FLOAT32 — use when maximum recall accuracy is critical and memory is not a concern
- BINARY — use for very large indexes where memory is the primary constraint
Precision is set at index creation time and cannot be changed without recreating the index.