Skip to content

feat: Add feature view versioning support to MongoDB online store - #6774

Open
alekseevpavel04 wants to merge 2 commits into
feast-dev:masterfrom
alekseevpavel04:feat/mongodb-fv-versioning
Open

feat: Add feature view versioning support to MongoDB online store#6774
alekseevpavel04 wants to merge 2 commits into
feast-dev:masterfrom
alekseevpavel04:feat/mongodb-fv-versioning

Conversation

@alekseevpavel04

Copy link
Copy Markdown

What this PR does / why we need it:

Adds feature view versioning to the MongoDB online store, so version-qualified
references such as driver_stats@v2:trips_today read and write the right data.
Until now MongoDB raised VersionedOnlineReadNotSupported for any versioned
reference, so versioning could not be used on MongoDB at all.

One deliberate departure from the issue, which points at sqlite.py. SQLite,
PostgreSQL, MySQL, FAISS, DynamoDB and Milvus all give each feature view its own
table or collection, so versioning there is a matter of appending _v{N} to that
table name via compute_table_id(). MongoDB is not shaped that way: it keeps
one collection per project ({project}_{collection_suffix}) and stores each
feature view inside it as a sub-document key — values under
features.<fv>.<feature>, the per-view timestamp under event_timestamps.<fv>.
Applying the sqlite.py pattern literally would give each version its own
collection, which splits a single entity's document across collections — an
unversioned read of another feature view on the same entity would stop working —
and duplicates every Atlas vector index.

So this follows redis.py instead, which is the only existing store with the same
shape (its feature view name is a key namespace rather than a table, and it uses
compute_versioned_name() rather than compute_table_id()). Concretely it adds a
module-level _versioned_fv_name(table, config) wrapping the shared
compute_versioned_name() helper, and applies it everywhere the feature view name
is used as a namespace:

  • _build_write_ops — shared by the sync and async write paths
  • online_read / online_read_async — the projection
  • _convert_raw_docs_to_proto — reading the values back out
  • retrieve_online_documents_v2 — the vector path, the Atlas index name, and the
    $vectorSearch filter prefix
  • update — the $unset for deleted feature views
  • _ensure_vector_indexes / _drop_vector_indexes_for_tables — index names and
    their path, so each version gets its own vector index

teardown is unchanged: it drops the whole collection, so every version goes with
it.

MongoDBOnlineStore is also added to the allow-list in
OnlineStore._is_versioned_read_supported() — without that entry a versioned read
still raises regardless of what the store does.

Behaviour with versioning off is unchanged. compute_versioned_name() returns
the bare name unless registry.enable_online_feature_view_versioning is set and a
non-zero version is present, so existing deployments write and read exactly the
same document keys as before. The two new parameters (fv_name on
_convert_raw_docs_to_proto, enable_versioning on the two vector-index helpers)
both default to the previous behaviour, so existing callers are unaffected.

One adjacent change: the VersionedOnlineReadNotSupported message lists the
stores that support versioned reads, and it was already out of date — Milvus is in
the allow-list but was missing from the sentence. Rather than add MongoDB to a
list that is wrong, this corrects the whole list. Happy to drop the Milvus half if
you would rather keep this to one thing.

Which issue(s) this PR fixes:

Fixes #6178

Checks

  • I've made sure the tests are passing.
  • My commits are signed off (git commit -s)
  • My PR title follows conventional commits format

Testing Strategy

  • Unit tests
  • Integration tests
  • Manual tests
  • Testing is not required for this change

New file sdk/python/tests/unit/infra/online_store/test_mongodb_versioning.py,
24 tests following the shape of the existing test_redis_versioning.py:

  • the naming helper: versioning off, version 0, and projection.version_tag
    winning over current_version_number
  • writes landing under the versioned namespace, and two versions landing in
    different ones
  • the read projection asking for the versioned namespace
  • the converter reading the versioned namespace, defaulting to table.name when
    no name is passed, and reporting "not found" for a version never written
  • update unsetting only the deleted version's namespace
  • Atlas vector index names and paths per version, and dropping the right one
  • MongoDBOnlineStore passing _check_versioned_read_support

With the versioning applied but reverted at the call sites, 10 of the 24 fail and
the 14 that pass are the unversioned-behaviour cases, which is the intended split.
Full sdk/python/tests/unit run matches the pre-change baseline with the 24 new
tests added and nothing else changed.

No integration test: this is namespace construction throughout, and exercising it
end to end needs a live MongoDB/Atlas, which the unit suite does not have.

Misc

The remaining ten sibling issues under #2728 (Bigtable, Datastore, Snowflake,
Couchbase, Elasticsearch, Hazelcast, HBase, Hybrid, Qdrant, Remote) are untouched
here. Happy to take another if this shape looks right to you.

MongoDB raised VersionedOnlineReadNotSupported for any version-qualified
reference, so feature view versioning could not be used on MongoDB at all.

Unlike the stores that already support this, MongoDB keeps one collection
per project and stores each feature view inside it as a sub-document key,
under features.<fv> and event_timestamps.<fv>. Versioning the collection
name would split one entity's document across collections and duplicate
every vector index, so the version qualifies the document namespace
instead, following redis.py rather than sqlite.py.

Adds _versioned_fv_name() and applies it on the write path, both read
paths, the document converter, the vector search path, update(), and the
Atlas vector index names and paths, so each version gets its own index.
teardown() is unchanged: it drops the whole collection.

Also registers MongoDBOnlineStore in the allow-list consulted by
OnlineStore._is_versioned_read_supported(), without which a versioned read
still raises regardless of what the store does.

With versioning disabled the document keys are byte-for-byte what they
were, and the two new parameters both default to the previous behaviour.

Signed-off-by: Pavel Alekseev <alekceevpavel@mail.ru>
Milvus has been in the allow-list consulted by
OnlineStore._is_versioned_read_supported() since versioned reads were added
to it, but was never added to the sentence VersionedOnlineReadNotSupported
prints, which tells the user which stores do support them. The message
therefore names a store set smaller than reality.

Signed-off-by: Pavel Alekseev <alekceevpavel@mail.ru>
@alekseevpavel04
alekseevpavel04 requested review from a team as code owners August 22, 2026 14:20
@alekseevpavel04
alekseevpavel04 requested review from HaoXuAI, nquinn408 and tokoko and removed request for a team August 22, 2026 14:20
@codecov-commenter

codecov-commenter commented Aug 22, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 67.74194% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.18%. Comparing base (f0bc070) to head (f1da3d6).

Files with missing lines Patch % Lines
...nfra/online_stores/mongodb_online_store/mongodb.py 67.74% 10 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6774      +/-   ##
==========================================
+ Coverage   47.09%   47.18%   +0.09%     
==========================================
  Files         419      419              
  Lines       51878    51890      +12     
  Branches     7525     7525              
==========================================
+ Hits        24430    24483      +53     
+ Misses      25700    25654      -46     
- Partials     1748     1753       +5     
Flag Coverage Δ
go-feature-server 30.58% <ø> (ø)
python-unit 48.49% <67.74%> (+0.09%) ⬆️
Files with missing lines Coverage Δ
sdk/python/feast/errors.py 73.26% <ø> (ø)
...k/python/feast/infra/online_stores/online_store.py 70.38% <ø> (ø)
...nfra/online_stores/mongodb_online_store/mongodb.py 55.90% <67.74%> (+14.93%) ⬆️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f0bc070...f1da3d6. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add feature view versioning support to MongoDB online store

2 participants