Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Field of Vector length
Signed-off-by: jyejare <jyejare@redhat.com>
  • Loading branch information
jyejare committed Apr 21, 2025
commit 93cb9f5744f47f98ae8839def8cb22076ab3e4eb
3 changes: 3 additions & 0 deletions protos/feast/core/Feature.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ message FeatureSpecV2 {

// Metric used for vector similarity search.
string vector_search_metric = 6;

// Field indicating the vector length
int32 vector_len = 7;
Comment thread
jyejare marked this conversation as resolved.
Outdated
}
12 changes: 12 additions & 0 deletions sdk/python/feast/feature_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -1555,6 +1555,18 @@ def _get_feature_view_and_df_for_online_write(
except Exception as _:
raise DataFrameSerializationError(df)

if feature_view.features[0].vector_index and df is not None:
fv_vector_feature_name = feature_view.features[0].name
df_vector_feature_index = df.columns.get_loc(fv_vector_feature_name)
if feature_view.features[0].vector_len != 0:
if (
feature_view.features[0].vector_len
!= df.shape[df_vector_feature_index]
):
raise ValueError(
f"The dataframe for {fv_vector_feature_name} column has {df.shape[1]} vectors, but the feature view {feature_view.name} expects {feature_view.features[0].vector_len}"
)

# # Apply transformations if this is an OnDemandFeatureView with write_to_online_store=True
if (
isinstance(feature_view, OnDemandFeatureView)
Expand Down
9 changes: 9 additions & 0 deletions sdk/python/feast/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Field:
description: A human-readable description.
tags: User-defined metadata in dictionary form.
vector_index: If set to True the field will be indexed for vector similarity search.
vector_len: The length of the vector if the vector index is set to True.
vector_search_metric: The metric used for vector similarity search.
"""

Expand All @@ -41,6 +42,7 @@ class Field:
description: str
tags: Dict[str, str]
vector_index: bool
vector_len: int
vector_search_metric: Optional[str]

def __init__(
Expand All @@ -51,6 +53,7 @@ def __init__(
description: str = "",
tags: Optional[Dict[str, str]] = None,
vector_index: bool = False,
vector_len: int = 0,
vector_search_metric: Optional[str] = None,
):
"""
Expand All @@ -69,6 +72,7 @@ def __init__(
self.description = description
self.tags = tags or {}
self.vector_index = vector_index
self.vector_len = vector_len
self.vector_search_metric = vector_search_metric

def __eq__(self, other):
Expand All @@ -80,6 +84,7 @@ def __eq__(self, other):
or self.dtype != other.dtype
or self.description != other.description
or self.tags != other.tags
or self.vector_len != other.vector_len
# or self.vector_index != other.vector_index
# or self.vector_search_metric != other.vector_search_metric
):
Expand All @@ -100,6 +105,7 @@ def __repr__(self):
f" description={self.description!r},\n"
f" tags={self.tags!r}\n"
f" vector_index={self.vector_index!r}\n"
f" vector_len={self.vector_len!r}\n"
f" vector_search_metric={self.vector_search_metric!r}\n"
f")"
)
Expand All @@ -117,6 +123,7 @@ def to_proto(self) -> FieldProto:
description=self.description,
tags=self.tags,
vector_index=self.vector_index,
vector_len=self.vector_len,
vector_search_metric=vector_search_metric,
)

Expand All @@ -131,12 +138,14 @@ def from_proto(cls, field_proto: FieldProto):
value_type = ValueType(field_proto.value_type)
vector_search_metric = getattr(field_proto, "vector_search_metric", "")
vector_index = getattr(field_proto, "vector_index", False)
vector_len = getattr(field_proto, "vector_len", 0)
return cls(
name=field_proto.name,
dtype=from_value_type(value_type=value_type),
tags=dict(field_proto.tags),
description=field_proto.description,
vector_index=vector_index,
vector_len=vector_len,
vector_search_metric=vector_search_metric,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def update(
for table in tables_to_keep:
table_name = _table_id(project, table)
if config.online_store.vector_enabled:
vector_value_type = f"vector"
vector_value_type = "vector"
else:
# keep the vector_value_type as BYTEA if pgvector is not enabled, to maintain compatibility
vector_value_type = "BYTEA"
Expand Down
2 changes: 1 addition & 1 deletion sdk/python/feast/protos/feast/core/Feature_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion sdk/python/feast/protos/feast/core/Feature_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class FeatureSpecV2(google.protobuf.message.Message):
DESCRIPTION_FIELD_NUMBER: builtins.int
VECTOR_INDEX_FIELD_NUMBER: builtins.int
VECTOR_SEARCH_METRIC_FIELD_NUMBER: builtins.int
VECTOR_LEN_FIELD_NUMBER: builtins.int
name: builtins.str
"""Name of the feature. Not updatable."""
value_type: feast.types.Value_pb2.ValueType.Enum.ValueType
Expand All @@ -68,6 +69,8 @@ class FeatureSpecV2(google.protobuf.message.Message):
"""Field indicating the vector will be indexed for vector similarity search"""
vector_search_metric: builtins.str
"""Metric used for vector similarity search."""
vector_len: builtins.int
"""Field indicating the vector length"""
def __init__(
self,
*,
Expand All @@ -77,7 +80,8 @@ class FeatureSpecV2(google.protobuf.message.Message):
description: builtins.str = ...,
vector_index: builtins.bool = ...,
vector_search_metric: builtins.str = ...,
vector_len: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "name", b"name", "tags", b"tags", "value_type", b"value_type", "vector_index", b"vector_index", "vector_search_metric", b"vector_search_metric"]) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["description", b"description", "name", b"name", "tags", b"tags", "value_type", b"value_type", "vector_index", b"vector_index", "vector_len", b"vector_len", "vector_search_metric", b"vector_search_metric"]) -> None: ...

global___FeatureSpecV2 = FeatureSpecV2
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def create_online_store(self) -> Dict[str, Any]:
"password": "test!@#$%",
"database": "test",
"vector_enabled": True,
"vector_len": 2,
"port": self.container.get_exposed_port(5432),
}

Expand Down