feast-dev / feast-dev/feast

Precomputed online retrieval does not preserve entity input order or duplicates

Open
#6,805 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
7.3k
Forks
1.4k
Avg merge
3d 16h
Merged PRs (30d)
15

Description

## Expected Behavior

When a precomputed FeatureService receives multiple entity rows, every feature value, field status, and event timestamp should be returned at the row of the corresponding input entity. Duplicate entities should appear at every requested row.

For example, a request for driver IDs `[3, 1, 3, 2]`, with a score of `driver_id * 10`, should return scores `[30.0, 10.0, 30.0, 20.0]`.

## Current Behavior

The precomputed read path calls `_get_unique_entities()`, which deduplicates and sorts entity keys before reading their vectors. However, `_try_precomputed_fast_path()` currently writes the returned vectors into response rows by enumeration order.

As a result, unordered requests can receive feature values belonging to different entities, and repeated entities are not fanned out to all requested rows. This is a user-facing correctness issue, not only an output ordering difference.

## Steps to reproduce

1. Define a FeatureService with `precompute_online=True`, an entity named `driver_id`, and a numeric feature such as `score`.
2. Populate precomputed vectors so each score is `driver_id * 10`.
3. Request online features with unordered and duplicate entity rows:

```python
response = store.get_online_features(
features=feature_service,
entity_rows={"driver_id": [3, 1, 3, 2]},
registry=registry,
project="test",
full_feature_names=True,
)
```

4. Observe that the feature values follow the sorted unique read order instead of the original request rows, and the duplicate row is not populated correctly.

The same behavior is present in `get_online_features_async()`.

### Specifications

- Version: current `master` at `5ad5592`; the affected path was introduced in #6463
- Platform: reproduced with Python 3.10.11 on macOS; the code path is platform-independent
- Subsystem: Python SDK / OnlineStore precomputed feature vector fast path

## Possible Solution

Pass the original row-index groups returned by `_get_unique_entities()` into the precomputed fast path. Scatter each decoded vector's values, field statuses, and event timestamp to every corresponding request row.

Add regression coverage at both the fast-path level and the synchronous/asynchronous public `get_online_features` APIs.

Contributor guide

Open the contributing guide

Research direction

Start by tracing `_get_unique_entities()` into `_try_precomputed_fast_path()` in the Python SDK OnlineStore path, then inspect the synchronous and asynchronous `get_online_features` entry points. Reproduce the request with entity IDs `[3, 1, 3, 2]` and precomputed scores, and add regression coverage at the fast-path and public API levels. Done means feature values, field statuses, and event timestamps appear in every original row, including duplicates, for both APIs.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design, data-engineering
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.