Skip to content

Python: use storage names for Redis search return fields and decode aliased vectors (#14753) - #14766

Open
MOHAMMED WASIM KHAN (wasim-builds) wants to merge 1 commit into
microsoft:mainfrom
wasim-builds:fix/redis-storage-name-return-fields
Open

MOHAMMED WASIM KHAN (wasim-builds) wants to merge 1 commit into
microsoft:mainfrom
wasim-builds:fix/redis-storage-name-return-fields

Conversation

@wasim-builds

Copy link
Copy Markdown
Contributor

Motivation and Context

Closes #14753

When a field in a Redis collection declares a storage_name, the collection creates its index attributes and stores its values under storage_name or name. However, _add_return_fields in RedisHashsetCollection and RedisJsonCollection asked the server to RETURN the declared field name. RediSearch only returns attributes named in RETURN, causing fields with a storage_name to be missing from search results. Furthermore, RedisHashsetCollection vector deserialization decoded the bytes into rec[field.name] while the subsequent data model step reads storage_name, leaving vectors as raw bytes.

Description

  • In RedisHashsetCollection._add_return_fields and RedisJsonCollection._add_return_fields, add field.storage_name or field.name to the query's return fields instead of field.name.
  • In RedisHashsetCollection._deserialize_store_models_to_dicts, decode vectors in-place under storage_name and also set rec[field.name].
  • Added unit tests in tests/unit/connectors/memory/test_redis_store.py covering return fields construction, search against RETURN-limited results, and vector deserialization with aliased storage names.

All 35 tests in tests/unit/connectors/memory/test_redis_store.py pass cleanly.
Co-authored with PRABHU KIRAN VANDRANKI (@VANDRANKI).

Contribution Checklist

…liased vectors (microsoft#14753)

The Redis Hashset and JSON collections create their index attributes and store their values under storage_name or name, but the search query asked the server to RETURN the declared field name. A field with a storage_name was therefore missing from every search result, and the Hashset vector decode wrote the array under the declared name while the data model step reads the storage name, so a vector with a storage_name came back as raw bytes.

Closes microsoft#14753

Co-authored-by: VANDRANKI <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks correct. Here's what I checked.

  • Index attributes. _definition_to_redis_fields builds every non-key field under field.storage_name or field.name. For hashsets that's the attribute name. For JSON it's $.{storage_name} with as_name=storage_name. RETURN has to name that attribute, which is what both _add_return_fields now do.
  • Vector search. It already uses the storage name (vector_field_name=vector_field.storage_name or vector_field.name, redis.py:378), so the vector query and the returned fields now agree.
  • Hashset vectors. _deserialize_dict_to_data_model reads record.get(field.storage_name or field.name) for dict and dataclass records, and pops storage_name to name for pydantic records. Decoding under storage_name is the key that step reads. The extra rec[field.name] copy is harmless for both.
  • JSON records. These need no change on the way back: values come out under the alias, and the data-model step maps them.
  • git merge-tree against main is clean.

I didn't run the tests.

Unrelated to this PR, but nearby: RedisJsonCollection._serialize_dicts_to_store_models assigns the vector field twice (the if field.field_type == "vector" line and the line after it do the same thing).

Reviewed with help from Claude Code.

This branch has not been deployed

No deployments
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.

Python: Bug: Redis search returns None for every field that declares a storage_name, because RETURN lists the declared name

4 participants