修改为东南天坐标系
This commit is contained in:
@@ -62,6 +62,7 @@ from chromadb.api.types import (
|
||||
IncludeMetadataDocuments,
|
||||
Loadable,
|
||||
Metadatas,
|
||||
ReadLevel,
|
||||
Schema,
|
||||
URIs,
|
||||
Where,
|
||||
@@ -697,6 +698,15 @@ class ServerAPI(BaseAPI, AdminAPI, Component):
|
||||
) -> CollectionModel:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> "IndexingStatus":
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def _search(
|
||||
self,
|
||||
@@ -704,6 +714,7 @@ class ServerAPI(BaseAPI, AdminAPI, Component):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
pass
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -19,8 +19,10 @@ from chromadb.api.types import (
|
||||
Embeddings,
|
||||
IDs,
|
||||
Include,
|
||||
IndexingStatus,
|
||||
Loadable,
|
||||
Metadatas,
|
||||
ReadLevel,
|
||||
Schema,
|
||||
URIs,
|
||||
Where,
|
||||
@@ -648,6 +650,15 @@ class AsyncServerAPI(AsyncBaseAPI, AsyncAdminAPI, Component):
|
||||
) -> CollectionModel:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> "IndexingStatus":
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def _search(
|
||||
self,
|
||||
@@ -655,6 +666,7 @@ class AsyncServerAPI(AsyncBaseAPI, AsyncAdminAPI, Component):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
pass
|
||||
|
||||
|
||||
@@ -32,8 +32,10 @@ from chromadb.api.types import (
|
||||
Embeddings,
|
||||
IDs,
|
||||
Include,
|
||||
IndexingStatus,
|
||||
Schema,
|
||||
Metadatas,
|
||||
ReadLevel,
|
||||
URIs,
|
||||
Where,
|
||||
WhereDocument,
|
||||
@@ -414,6 +416,27 @@ class AsyncFastAPI(BaseHTTPClient, AsyncServerAPI):
|
||||
model = CollectionModel.from_json(resp_json)
|
||||
return model
|
||||
|
||||
@trace_method(
|
||||
"AsyncFastAPI._get_indexing_status", OpenTelemetryGranularity.OPERATION
|
||||
)
|
||||
@override
|
||||
async def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> IndexingStatus:
|
||||
resp_json = await self._make_request(
|
||||
"get",
|
||||
f"/tenants/{tenant}/databases/{database}/collections/{collection_id}/indexing_status",
|
||||
)
|
||||
return IndexingStatus(
|
||||
num_indexed_ops=resp_json["num_indexed_ops"],
|
||||
num_unindexed_ops=resp_json["num_unindexed_ops"],
|
||||
total_ops=resp_json["total_ops"],
|
||||
op_indexing_progress=resp_json["op_indexing_progress"],
|
||||
)
|
||||
|
||||
@trace_method("AsyncFastAPI._search", OpenTelemetryGranularity.OPERATION)
|
||||
@override
|
||||
async def _search(
|
||||
@@ -422,9 +445,13 @@ class AsyncFastAPI(BaseHTTPClient, AsyncServerAPI):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
"""Performs hybrid search on a collection"""
|
||||
payload = {"searches": [s.to_dict() for s in searches]}
|
||||
payload = {
|
||||
"searches": [s.to_dict() for s in searches],
|
||||
"read_level": read_level,
|
||||
}
|
||||
|
||||
resp_json = await self._make_request(
|
||||
"post",
|
||||
|
||||
@@ -26,8 +26,10 @@ from chromadb.api.types import (
|
||||
Embeddings,
|
||||
IDs,
|
||||
Include,
|
||||
IndexingStatus,
|
||||
Schema,
|
||||
Metadatas,
|
||||
ReadLevel,
|
||||
URIs,
|
||||
Where,
|
||||
WhereDocument,
|
||||
@@ -379,6 +381,25 @@ class FastAPI(BaseHTTPClient, ServerAPI):
|
||||
model = CollectionModel.from_json(resp_json)
|
||||
return model
|
||||
|
||||
@trace_method("FastAPI._get_indexing_status", OpenTelemetryGranularity.OPERATION)
|
||||
@override
|
||||
def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> IndexingStatus:
|
||||
resp_json = self._make_request(
|
||||
"get",
|
||||
f"/tenants/{tenant}/databases/{database}/collections/{collection_id}/indexing_status",
|
||||
)
|
||||
return IndexingStatus(
|
||||
num_indexed_ops=resp_json["num_indexed_ops"],
|
||||
num_unindexed_ops=resp_json["num_unindexed_ops"],
|
||||
total_ops=resp_json["total_ops"],
|
||||
op_indexing_progress=resp_json["op_indexing_progress"],
|
||||
)
|
||||
|
||||
@trace_method("FastAPI._search", OpenTelemetryGranularity.OPERATION)
|
||||
@override
|
||||
def _search(
|
||||
@@ -387,10 +408,14 @@ class FastAPI(BaseHTTPClient, ServerAPI):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
"""Performs hybrid search on a collection"""
|
||||
# Convert Search objects to dictionaries
|
||||
payload = {"searches": [s.to_dict() for s in searches]}
|
||||
payload = {
|
||||
"searches": [s.to_dict() for s in searches],
|
||||
"read_level": read_level,
|
||||
}
|
||||
|
||||
resp_json = self._make_request(
|
||||
"post",
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Attachable function definitions for ChromaDB collections.
|
||||
|
||||
This module provides function constants that can be attached to collections
|
||||
to perform automatic computations on collection data.
|
||||
|
||||
Example:
|
||||
>>> from chromadb.api.functions import STATISTICS_FUNCTION
|
||||
>>> attached_fn = collection.attach_function(
|
||||
... function=STATISTICS_FUNCTION,
|
||||
... name="my_stats",
|
||||
... output_collection="my_stats_output"
|
||||
... )
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Function(str, Enum):
|
||||
"""Available functions that can be attached to collections."""
|
||||
|
||||
STATISTICS = "statistics"
|
||||
"""Computes metadata value frequencies for a collection."""
|
||||
|
||||
RECORD_COUNTER = "record_counter"
|
||||
"""Counts records in a collection."""
|
||||
|
||||
# Used only for failure testing - not a real function
|
||||
_NONEXISTENT_TEST_ONLY = "nonexistent_function"
|
||||
|
||||
|
||||
# Convenience aliases for cleaner imports
|
||||
STATISTICS_FUNCTION = Function.STATISTICS
|
||||
RECORD_COUNTER_FUNCTION = Function.RECORD_COUNTER
|
||||
@@ -6,6 +6,7 @@ from chromadb.api.types import (
|
||||
Embedding,
|
||||
PyEmbedding,
|
||||
Include,
|
||||
IndexingStatus,
|
||||
Metadata,
|
||||
Document,
|
||||
Image,
|
||||
@@ -15,6 +16,7 @@ from chromadb.api.types import (
|
||||
QueryResult,
|
||||
ID,
|
||||
OneOrMany,
|
||||
ReadLevel,
|
||||
WhereDocument,
|
||||
SearchResult,
|
||||
maybe_cast_one_to_many,
|
||||
@@ -96,6 +98,22 @@ class AsyncCollection(CollectionCommon["AsyncServerAPI"]):
|
||||
database=self.database,
|
||||
)
|
||||
|
||||
async def get_indexing_status(self) -> IndexingStatus:
|
||||
"""Get the indexing status of this collection.
|
||||
|
||||
Returns:
|
||||
IndexingStatus: An object containing:
|
||||
- num_indexed_ops: Number of user operations that have been indexed
|
||||
- num_unindexed_ops: Number of user operations pending indexing
|
||||
- total_ops: Total number of user operations in collection
|
||||
- op_indexing_progress: Proportion of user operations that have been indexed as a float between 0 and 1
|
||||
"""
|
||||
return await self._client._get_indexing_status(
|
||||
collection_id=self.id,
|
||||
tenant=self.tenant,
|
||||
database=self.database,
|
||||
)
|
||||
|
||||
async def get(
|
||||
self,
|
||||
ids: Optional[OneOrMany[ID]] = None,
|
||||
@@ -294,6 +312,7 @@ class AsyncCollection(CollectionCommon["AsyncServerAPI"]):
|
||||
async def search(
|
||||
self,
|
||||
searches: OneOrMany[Search],
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
"""Perform hybrid search on the collection.
|
||||
This is an experimental API that only works for Hosted Chroma for now.
|
||||
@@ -304,6 +323,11 @@ class AsyncCollection(CollectionCommon["AsyncServerAPI"]):
|
||||
- rank: Ranking expression for hybrid search (defaults to Val(0.0))
|
||||
- limit: Limit configuration for pagination (defaults to no limit)
|
||||
- select: Select configuration for keys to return (defaults to empty)
|
||||
read_level: Controls whether to read from the write-ahead log (WAL):
|
||||
- ReadLevel.INDEX_AND_WAL: Read from both the compacted index and WAL (default).
|
||||
All committed writes will be visible.
|
||||
- ReadLevel.INDEX_ONLY: Read only from the compacted index, skipping the WAL.
|
||||
Faster, but recent writes that haven't been compacted may not be visible.
|
||||
|
||||
Returns:
|
||||
SearchResult: Column-major format response with:
|
||||
@@ -351,6 +375,10 @@ class AsyncCollection(CollectionCommon["AsyncServerAPI"]):
|
||||
Search().where(K("type") == "paper").rank(Knn(query=[0.3, 0.4]))
|
||||
]
|
||||
results = await collection.search(searches)
|
||||
|
||||
# Skip WAL for faster queries (may miss recent uncommitted writes)
|
||||
from chromadb.api.types import ReadLevel
|
||||
result = await collection.search(search, read_level=ReadLevel.INDEX_ONLY)
|
||||
"""
|
||||
# Convert single search to list for consistent handling
|
||||
searches_list = maybe_cast_one_to_many(searches)
|
||||
@@ -367,6 +395,7 @@ class AsyncCollection(CollectionCommon["AsyncServerAPI"]):
|
||||
searches=cast(List[Search], embedded_searches),
|
||||
tenant=self.tenant,
|
||||
database=self.database,
|
||||
read_level=read_level,
|
||||
)
|
||||
|
||||
async def update(
|
||||
|
||||
@@ -7,6 +7,7 @@ from chromadb.api.types import (
|
||||
Embedding,
|
||||
PyEmbedding,
|
||||
Include,
|
||||
IndexingStatus,
|
||||
Metadata,
|
||||
Document,
|
||||
Image,
|
||||
@@ -16,6 +17,7 @@ from chromadb.api.types import (
|
||||
QueryResult,
|
||||
ID,
|
||||
OneOrMany,
|
||||
ReadLevel,
|
||||
WhereDocument,
|
||||
SearchResult,
|
||||
maybe_cast_one_to_many,
|
||||
@@ -50,6 +52,22 @@ class Collection(CollectionCommon["ServerAPI"]):
|
||||
database=self.database,
|
||||
)
|
||||
|
||||
def get_indexing_status(self) -> IndexingStatus:
|
||||
"""Get the indexing status of this collection.
|
||||
|
||||
Returns:
|
||||
IndexingStatus: An object containing:
|
||||
- num_indexed_ops: Number of user operations that have been indexed
|
||||
- num_unindexed_ops: Number of user operations pending indexing
|
||||
- total_ops: Total number of user operations in collection
|
||||
- op_indexing_progress: Proportion of user operations that have been indexed as a float between 0 and 1
|
||||
"""
|
||||
return self._client._get_indexing_status(
|
||||
collection_id=self.id,
|
||||
tenant=self.tenant,
|
||||
database=self.database,
|
||||
)
|
||||
|
||||
def add(
|
||||
self,
|
||||
ids: OneOrMany[ID],
|
||||
@@ -303,6 +321,7 @@ class Collection(CollectionCommon["ServerAPI"]):
|
||||
def search(
|
||||
self,
|
||||
searches: OneOrMany[Search],
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
"""Perform hybrid search on the collection.
|
||||
This is an experimental API that only works for Hosted Chroma for now.
|
||||
@@ -313,6 +332,11 @@ class Collection(CollectionCommon["ServerAPI"]):
|
||||
- rank: Ranking expression for hybrid search (defaults to Val(0.0))
|
||||
- limit: Limit configuration for pagination (defaults to no limit)
|
||||
- select: Select configuration for keys to return (defaults to empty)
|
||||
read_level: Controls whether to read from the write-ahead log (WAL):
|
||||
- ReadLevel.INDEX_AND_WAL: Read from both the compacted index and WAL (default).
|
||||
All committed writes will be visible.
|
||||
- ReadLevel.INDEX_ONLY: Read only from the compacted index, skipping the WAL.
|
||||
Faster, but recent writes that haven't been compacted may not be visible.
|
||||
|
||||
Returns:
|
||||
SearchResult: Column-major format response with:
|
||||
@@ -360,6 +384,10 @@ class Collection(CollectionCommon["ServerAPI"]):
|
||||
Search().where(K("type") == "paper").rank(Knn(query=[0.3, 0.4]))
|
||||
]
|
||||
results = collection.search(searches)
|
||||
|
||||
# Skip WAL for faster queries (may miss recent uncommitted writes)
|
||||
from chromadb.api.types import ReadLevel
|
||||
result = collection.search(search, read_level=ReadLevel.INDEX_ONLY)
|
||||
"""
|
||||
# Convert single search to list for consistent handling
|
||||
searches_list = maybe_cast_one_to_many(searches)
|
||||
@@ -376,6 +404,7 @@ class Collection(CollectionCommon["ServerAPI"]):
|
||||
searches=cast(List[Search], embedded_searches),
|
||||
tenant=self.tenant,
|
||||
database=self.database,
|
||||
read_level=read_level,
|
||||
)
|
||||
|
||||
def update(
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -39,6 +39,7 @@ from chromadb.api.types import (
|
||||
IncludeMetadataDocuments,
|
||||
IncludeMetadataDocumentsDistances,
|
||||
IncludeMetadataDocumentsEmbeddings,
|
||||
ReadLevel,
|
||||
Schema,
|
||||
SearchResult,
|
||||
)
|
||||
@@ -334,6 +335,15 @@ class RustBindingsAPI(ServerAPI):
|
||||
"Collection forking is not implemented for Local Chroma"
|
||||
)
|
||||
|
||||
@override
|
||||
def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> "IndexingStatus":
|
||||
raise NotImplementedError("Indexing status is not implemented for Local Chroma")
|
||||
|
||||
@override
|
||||
def _search(
|
||||
self,
|
||||
@@ -341,6 +351,7 @@ class RustBindingsAPI(ServerAPI):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
raise NotImplementedError("Search is not implemented for Local Chroma")
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ from chromadb.api.types import (
|
||||
Embeddings,
|
||||
Metadatas,
|
||||
Documents,
|
||||
ReadLevel,
|
||||
Schema,
|
||||
URIs,
|
||||
Where,
|
||||
@@ -432,6 +433,15 @@ class SegmentAPI(ServerAPI):
|
||||
"Collection forking is not implemented for SegmentAPI"
|
||||
)
|
||||
|
||||
@override
|
||||
def _get_indexing_status(
|
||||
self,
|
||||
collection_id: UUID,
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
) -> "IndexingStatus":
|
||||
raise NotImplementedError("Indexing status is not implemented for SegmentAPI")
|
||||
|
||||
@override
|
||||
def _search(
|
||||
self,
|
||||
@@ -439,6 +449,7 @@ class SegmentAPI(ServerAPI):
|
||||
searches: List[Search],
|
||||
tenant: str = DEFAULT_TENANT,
|
||||
database: str = DEFAULT_DATABASE,
|
||||
read_level: ReadLevel = ReadLevel.INDEX_AND_WAL,
|
||||
) -> SearchResult:
|
||||
raise NotImplementedError("Search is not implemented for SegmentAPI")
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ __all__ = [
|
||||
"UpdateMetadata",
|
||||
"SearchResult",
|
||||
"SearchResultRow",
|
||||
"IndexingStatus",
|
||||
"SparseVector",
|
||||
# Index Configuration Types
|
||||
"FtsIndexConfig",
|
||||
@@ -619,6 +620,14 @@ class QueryResult(TypedDict):
|
||||
included: Include
|
||||
|
||||
|
||||
@dataclass
|
||||
class IndexingStatus:
|
||||
num_indexed_ops: int
|
||||
num_unindexed_ops: int
|
||||
total_ops: int
|
||||
op_indexing_progress: float
|
||||
|
||||
|
||||
class SearchResultRow(TypedDict, total=False):
|
||||
"""A single row from search results.
|
||||
|
||||
@@ -751,6 +760,20 @@ class IndexMetadata(TypedDict):
|
||||
Space = Literal["cosine", "l2", "ip"]
|
||||
|
||||
|
||||
class ReadLevel(str, Enum):
|
||||
"""Controls whether search queries read from the write-ahead log (WAL).
|
||||
|
||||
Attributes:
|
||||
INDEX_AND_WAL: Read from both the compacted index and the WAL (default).
|
||||
All committed writes will be visible.
|
||||
INDEX_ONLY: Read only from the compacted index, skipping the WAL.
|
||||
Faster, but recent writes that haven't been compacted may not be visible.
|
||||
"""
|
||||
|
||||
INDEX_AND_WAL = "index_and_wal"
|
||||
INDEX_ONLY = "index_only"
|
||||
|
||||
|
||||
# TODO: make warnings prettier and add link to migration docs
|
||||
@runtime_checkable
|
||||
class EmbeddingFunction(Protocol[D]):
|
||||
@@ -767,7 +790,8 @@ class EmbeddingFunction(Protocol[D]):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self, input: D) -> Embeddings: ...
|
||||
def __call__(self, input: D) -> Embeddings:
|
||||
...
|
||||
|
||||
def embed_query(self, input: D) -> Embeddings:
|
||||
"""
|
||||
@@ -951,7 +975,8 @@ def validate_embedding_function(
|
||||
|
||||
|
||||
class DataLoader(Protocol[L]):
|
||||
def __call__(self, uris: URIs) -> L: ...
|
||||
def __call__(self, uris: URIs) -> L:
|
||||
...
|
||||
|
||||
|
||||
def validate_ids(ids: IDs) -> IDs:
|
||||
@@ -1408,7 +1433,8 @@ class SparseEmbeddingFunction(Protocol[D]):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self, input: D) -> SparseVectors: ...
|
||||
def __call__(self, input: D) -> SparseVectors:
|
||||
...
|
||||
|
||||
def embed_query(self, input: D) -> SparseVectors:
|
||||
"""
|
||||
@@ -1602,9 +1628,9 @@ class VectorIndexConfig(BaseModel):
|
||||
|
||||
space: Optional[Space] = None
|
||||
embedding_function: Optional[Any] = DefaultEmbeddingFunction()
|
||||
source_key: Optional[str] = (
|
||||
None # key to source the vector from (accepts str or Key)
|
||||
)
|
||||
source_key: Optional[
|
||||
str
|
||||
] = None # key to source the vector from (accepts str or Key)
|
||||
hnsw: Optional[HnswIndexConfig] = None
|
||||
spann: Optional[SpannIndexConfig] = None
|
||||
|
||||
@@ -1653,9 +1679,9 @@ class SparseVectorIndexConfig(BaseModel):
|
||||
|
||||
# TODO(Sanket): Change this to the appropriate sparse ef and use a default here.
|
||||
embedding_function: Optional[Any] = None
|
||||
source_key: Optional[str] = (
|
||||
None # key to source the sparse vector from (accepts str or Key)
|
||||
)
|
||||
source_key: Optional[
|
||||
str
|
||||
] = None # key to source the sparse vector from (accepts str or Key)
|
||||
bm25: Optional[bool] = None
|
||||
|
||||
@field_validator("source_key", mode="before")
|
||||
|
||||
Reference in New Issue
Block a user