fix: preserve custom metadata when updating memory (#4495)

This commit is contained in:
Kartik
2026-03-24 10:58:21 +05:30
committed by GitHub
parent bda5b726bd
commit 5431badfd4
2 changed files with 47 additions and 2 deletions
+2 -1
View File
@@ -197,7 +197,8 @@ class MongoDB(VectorStoreBase):
if vector is not None:
update_fields["embedding"] = vector
if payload is not None:
update_fields["payload"] = payload
for key, value in payload.items():
update_fields[f"payload.{key}"] = value
if update_fields:
try:
+45 -1
View File
@@ -203,6 +203,10 @@ def test_delete(mongo_vector_fixture):
def test_update(mongo_vector_fixture):
"""
Test that update() uses dot notation for payload fields instead of replacing
the entire payload document.
"""
mongo_vector, mock_collection, _ = mongo_vector_fixture
vector_id = "id1"
updated_vector = [0.3] * 1536
@@ -212,11 +216,51 @@ def test_update(mongo_vector_fixture):
mongo_vector.update(vector_id=vector_id, vector=updated_vector, payload=updated_payload)
# Should use dot notation (payload.name) instead of full replacement (payload)
mock_collection.update_one.assert_called_once_with(
{"_id": vector_id}, {"$set": {"embedding": updated_vector, "payload": updated_payload}}
{"_id": vector_id}, {"$set": {"embedding": updated_vector, "payload.name": "updated_vector"}}
)
def test_update_payload_only_uses_dot_notation(mongo_vector_fixture):
"""
Test that updating only the payload uses dot notation for each field,
preserving existing metadata fields not included in the update.
"""
mongo_vector, mock_collection, _ = mongo_vector_fixture
mock_collection.update_one.return_value = MagicMock(matched_count=1)
mongo_vector.update(
vector_id="id1",
payload={"data": "updated text", "hash": "def456", "updated_at": "2025-06-01"},
)
set_arg = mock_collection.update_one.call_args[0][1]["$set"]
# Only the specified fields should be in $set, using dot notation
assert set_arg == {
"payload.data": "updated text",
"payload.hash": "def456",
"payload.updated_at": "2025-06-01",
}
# "payload" key itself should NOT appear (that would replace the whole document)
assert "payload" not in set_arg
def test_update_vector_only_does_not_touch_payload(mongo_vector_fixture):
"""Test that updating only the vector does not touch any payload fields."""
mongo_vector, mock_collection, _ = mongo_vector_fixture
mock_collection.update_one.return_value = MagicMock(matched_count=1)
mongo_vector.update(vector_id="id1", vector=[0.7, 0.8, 0.9])
set_arg = mock_collection.update_one.call_args[0][1]["$set"]
assert set_arg == {"embedding": [0.7, 0.8, 0.9]}
assert not any(k.startswith("payload.") for k in set_arg)
def test_get(mongo_vector_fixture):
mongo_vector, mock_collection, _ = mongo_vector_fixture
vector_id = "id1"