fix: preserve custom metadata when updating memory (#4495)
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user