fix(storage): pin Redis client to RESP2 so FT.SEARCH decodes correctly#3
Merged
Conversation
Symptom: every /query call against a freshly-ingested index returned
zero sources even when keyword and vector matches existed in the
underlying Redis. Direct ``redis-cli FT.SEARCH ...`` from the host
returned the expected docs; the kg-api Python path returned 0.
Root cause: Redis Stack 7.2+ negotiates RESP3 by default. On RESP3
the FT.SEARCH reply is a dict:
{b'total_results': N, b'results': [...], b'attributes': [...], ...}
The ``ft().search()`` helper in redis-py still parses the legacy RESP2
positional list shape (``[count, doc_id, doc_data, ...]``). Faced
with a dict it silently produces ``total=0, docs=[]`` — looks like
"no matches" instead of a decode failure.
Fix: pass ``protocol=2`` to ``aioredis.from_url`` in
``RedisVectorStore.__init__``. Forces the connection to RESP2 so the
server replies with the positional list the helper expects.
Verified end-to-end on the kairos market-news namespace:
Q='mps' sources=5
Q='FTSE MIB' sources=7
Q='borsa italiana' sources=6
(Previously all three returned 0 with identical data in Redis.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every
/querycall against a freshly-ingested index returned zero sources even when keyword and vector matches existed in the underlying Redis Stack.redis-cli FT.SEARCH …from the host returned the expected docs; the Python path throughRedisVectorStorereturned 0.Root cause
Redis Stack 7.2+ negotiates RESP3 by default. On RESP3 the
FT.SEARCHreply is a dict:```python
{b'total_results': N, b'results': [...], b'attributes': [...], ...}
```
The
ft().search()helper inredis-pystill parses the legacy RESP2 positional list shape ([count, doc_id, doc_data, ...]). Faced with a dict it silently producestotal=0, docs=[]— looks like "no matches" instead of a decode failure.Fix
Pass
protocol=2toaioredis.from_urlinRedisVectorStore.__init__. Forces the connection to RESP2 so the server replies with the positional list the helper expects. One-line change.Verified end-to-end (against a 32-chunk ingested namespace)
Before:
```
Q='mps' -> sources=0
Q='FTSE MIB' -> sources=0
Q='borsa italiana' -> sources=0
```
After:
```
Q='mps' -> sources=5
Q='FTSE MIB' -> sources=7
Q='borsa italiana' -> sources=6
```
Same data, same Redis, same query, only difference is the protocol flag.
Test plan
🤖 Generated with Claude Code