Repository navigation
Conversation
The Milvus online store had no operation between upsert and dropping a collection, so a row could not be removed when its entity left the catalogue. The Redis online store can remove rows with delete_entity_values and delete_table. MilvusOnlineStore.online_delete deletes rows by entity key or by filter. It accepts exactly one of the two, deletes nothing for an empty key list, rejects a filter without conditions, and does not create a missing collection. It works on every collection that Feast created. Signed-off-by: jiwidi <fhjaime96@gmail.com>
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #7082 +/- ##
==========================================
+ Coverage 50.97% 51.00% +0.02%
==========================================
Files 455 455
Lines 56994 57013 +19
Branches 8321 8327 +6
==========================================
+ Hits 29055 29080 +25
+ Misses 25954 25947 -7
- Partials 1985 1986 +1
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Signed-off-by: jiwidi <fhjaime96@gmail.com>
patelchaitany
left a comment
There was a problem hiding this comment.
Looks good overall. One concern about nested empty filter groups on the delete path, and a small nit.
| expression = MilvusFilterTranslator().translate(filters) | ||
| if not expression: | ||
| raise ValueError("The deletion filter must have at least one condition") |
There was a problem hiding this comment.
This only catches a filter that is empty at the top level. MilvusFilterTranslator drops empty nested groups, so:
CompoundFilter(type="and", filters=[
ComparisonFilter(type="eq", key="brand_id", value="acme"),
CompoundFilter(type="or", filters=[]),
])becomes (brand_id == 'acme') and deletes every acme row. An empty or should match nothing, so this deletes more than the filter asks for. It can happen when the or is built from a list that turns out empty. Since this is a delete, could we reject an empty group anywhere in the tree, not only at the top?
| collection = self._get_or_create_collection(config, table) | ||
| self.client.delete(collection_name=collection["collection_name"], **selector) |
There was a problem hiding this comment.
nit: The guard above already returns when the collection is missing, so this never creates one. It is only here to load and cache the collection. A short comment would help, since it reads like "create, then delete". Also, collection["collection_name"] is the same as collection_name.
The Milvus filter translator drops an empty nested group, so a filter such as and(brand_id == 'acme', or()) deleted every acme row instead of none. online_delete now rejects a filter with an empty group at any level before it connects. The delete path loads the collection with _ensure_loaded instead of _get_or_create_collection, which could not create one after the has_collection guard, and reuses the collection name it computed. Signed-off-by: jiwidi <fhjaime96@gmail.com>
hi! thank you for review, pushed now a commit to address the bug and nit.
|
Signed-off-by: jiwidi <fhjaime96@gmail.com>
What this PR does / why we need it:
The Redis online store can remove rows:
delete_entity_valuesremoves the rows of an entity anddelete_tableremoves the rows of a feature view. The Milvus online store has nothing betweenupsertanddrop_collection, so a row cannot be removed when its entity leaves the data set, forexample a product that is no longer sold.
This PR adds
MilvusOnlineStore.online_delete, which deletes by entity key or by filter:entity_keys=[...]filters=ComparisonFilter(...)orCompoundFilter(...)MilvusFilterTranslator.entity_keys=[]ValueError.ValueError, so a mistake cannot delete more rows than it names.It works on every collection Feast created, whichever settings created it. No tombstone is kept: a
later write creates the row again, and Feast does not order a delete against writes from other
processes. The method is store-level, like the Redis delete methods; a
FeatureStore-level API canfollow once more stores implement it.
Which issue(s) this PR fixes:
N/A
Checks
git commit -s)Testing Strategy
Unit tests
Integration tests
Manual tests
Testing is not required for this change
Unit (Milvus Lite): delete by entity key leaves the other rows; delete by filter; a deleted row
can be written again.
Unit (mocked client): both or neither selector and a filter with an empty group are rejected
before any call; a missing collection is neither created nor queried; an empty key list
does not even connect.
Server: delete by key and by filter are visible to the next
Strongread; the row can bewritten again.
Unit tests run on Milvus Lite 3.2.1 (pymilvus 3.0.2). The server test in
sdk/python/tests/integration/online_store/test_milvus_remote.pypasses against a localMilvus 3.0.2 server. The existing Milvus unit and server tests pass unchanged.
Misc
Part of a stack that adds to the Milvus online store the update and delete functionality the Redis
online store has, following #6882, #6895, #6917, #6921 and #6940. The other PRs of the stack are
#7083 (partition options) and #7084 (tie-break in write batches).
mutation_timeoutand a schema mismatch check follow once these merge.