Precomputed online retrieval does not preserve entity input order or duplicates
- 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
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