Skip to content

Commit d447db2

Browse files
authored
Avoid requesting features from OnlineStore twice (feast-dev#2185)
* Avoid requesting features from OnlineStore twice Signed-off-by: Judah Rand <[email protected]> * Fix edge case where multiple ODFVs reference the same FeatureView. Signed-off-by: Judah Rand <[email protected]>
1 parent ecdf15e commit d447db2

File tree

1 file changed

+36
-13
lines changed

1 file changed

+36
-13
lines changed

sdk/python/feast/feature_store.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,9 @@ def get_online_features(
11441144
# Also create entity values to append to the result
11451145
result_rows.append(_entity_row_to_field_values(entity_row_proto))
11461146

1147+
# Keep track of what has been requested from the OnlineStore
1148+
# to avoid requesting the same thing twice for ODFVs.
1149+
retrieved_feature_refs: Set[str] = set()
11471150
for table, requested_features in grouped_refs:
11481151
table_join_keys = [
11491152
entity_name_to_join_key_map[entity_name]
@@ -1158,6 +1161,11 @@ def get_online_features(
11581161
table,
11591162
union_of_entity_keys,
11601163
)
1164+
table_feature_names = {feature.name for feature in table.features}
1165+
retrieved_feature_refs |= {
1166+
f"{table.name}:{feature}" if feature in table_feature_names else feature
1167+
for feature in requested_features
1168+
}
11611169

11621170
requested_result_row_names = self._get_requested_result_fields(
11631171
result_rows, needed_request_fv_features
@@ -1170,6 +1178,7 @@ def get_online_features(
11701178
request_data_features,
11711179
result_rows,
11721180
union_of_entity_keys,
1181+
retrieved_feature_refs,
11731182
)
11741183

11751184
self._augment_response_with_on_demand_transforms(
@@ -1205,6 +1214,7 @@ def _populate_odfv_dependencies(
12051214
request_data_features: Dict[str, List[Any]],
12061215
result_rows: List[GetOnlineFeaturesResponse.FieldValues],
12071216
union_of_entity_keys: List[EntityKeyProto],
1217+
retrieved_feature_refs: Set[str],
12081218
):
12091219
# Add more feature values to the existing result rows for the request data features
12101220
for feature_name, feature_values in request_data_features.items():
@@ -1223,19 +1233,32 @@ def _populate_odfv_dependencies(
12231233
if len(grouped_odfv_refs) > 0:
12241234
for odfv, _ in grouped_odfv_refs:
12251235
for fv in odfv.input_feature_views.values():
1226-
table_join_keys = [
1227-
entity_name_to_join_key_map[entity_name]
1228-
for entity_name in fv.entities
1229-
]
1230-
self._populate_result_rows_from_feature_view(
1231-
table_join_keys,
1232-
full_feature_names,
1233-
provider,
1234-
[feature.name for feature in fv.features],
1235-
result_rows,
1236-
fv,
1237-
union_of_entity_keys,
1238-
)
1236+
# Find the set of required Features which have not yet
1237+
# been retrieved.
1238+
not_yet_retrieved = {
1239+
feature.name
1240+
for feature in fv.projection.features
1241+
if f"{fv.name}:{feature.name}" not in retrieved_feature_refs
1242+
}
1243+
# If there are required Features which have not yet been retrieved
1244+
# retrieve them.
1245+
if not_yet_retrieved:
1246+
table_join_keys = [
1247+
entity_name_to_join_key_map[entity_name]
1248+
for entity_name in fv.entities
1249+
]
1250+
self._populate_result_rows_from_feature_view(
1251+
table_join_keys,
1252+
full_feature_names,
1253+
provider,
1254+
list(not_yet_retrieved),
1255+
result_rows,
1256+
fv,
1257+
union_of_entity_keys,
1258+
)
1259+
# Update the set of retrieved Features with any newly retrieved
1260+
# Features.
1261+
retrieved_feature_refs |= not_yet_retrieved
12391262

12401263
def get_needed_request_data(
12411264
self,

0 commit comments

Comments
 (0)