3

I'm using the following test code to experiment with RediSearch using RedisJSON data. I would expect client.ft(candles_index).search("4h") to return the JSON data in the candles list, but there are no results returned.

I've been using some of the unit tests from redis-py as reference for some of my code, and I've include the runtime output as well to show some of the output along the way that I've been using to try and see where I might have gone wrong.

I've tried various adjustments the root references in the schema between ., .., $. and $.. to see if it might be a root matching issue, but it doesn't seem to be.

ANSWER

I think I must have erroneously tested the $.. path schema variation in my early testing. That was the secret sauce to get this working for me. Code and results updated, along with another variation I found here

import json
import redis
from redis.commands.json.path import Path
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.field import TextField

roots = ('candles', 'symbols')

symbols = [ 
            {
                "name": "DOGEUSDT",
                "id": 19948
            }
        ]

candles = [
            {
                "stream_name": "dogeusdt@kline_4h",
                "symbol_name": "DOGEUSDT",
                "symbol_id": 19948,
                "timeframe_name": "4h",
                "timeframe_id": 1914,
                "open_time": 1639699200000,
                "open": 1.1,
                "high": 1.2,
                "low": 1.3,
                "close": 1.4,
                "close_time": 1639713599999,
                "candle_id": 1
            }
        ]

client = redis.Redis()

client.flushall()

candles_index = 'candles'
symbols_index = 'symbols'
index_names = [candles_index, symbols_index]

candle_index_definition = IndexDefinition(index_type=IndexType.JSON, prefix=[candles_index])
candle_index_schema = (
    TextField('$..stream_name', as_name='stream_name'),
    TextField('$..symbol_name', as_name='symbol_name'),
    TextField('$..timeframe_name', as_name='timeframe_name'),
    )

for index in index_names:
    try:
        client.ft(index).info()
    except Exception as e:
        pass
    else:
        print(f'{index} {client.ft(index).info()}')
        print('dropping index')
        try:
            client.ft(index).dropindex()
        except Exception as e:
            pass

client.ft(candles_index).create_index(candle_index_schema, definition=candle_index_definition)

for root in roots:
    client.json().set(root, Path.rootPath(), [])

for candle in candles:
    client.json().arrappend('candles', Path.rootPath(), candle)

print(f"client.json().get('candles'):\n{json.dumps(client.json().get('candles'),indent=2)}")
print(f'')
print(f'client.ft(candles_index).info():\n{client.ft(candles_index).info()}')
print(f'')
print(f'client.ft(candles_index).search("*"):\n{client.ft(candles_index).search("*")}')
print(f'')
print(f'client.ft(candles_index).search("4h"):\n{client.ft(candles_index).search("4h")}')
print(f'')
print(f'client.ft(candles_index).search("@timeframe_name:(4h)"):\n{client.ft(candles_index).search("@timeframe_name:(4h)")}')
# python3 test.py
client.json().get('candles'):
[
  {
    "stream_name": "dogeusdt@kline_4h",
    "symbol_name": "DOGEUSDT",
    "symbol_id": 19948,
    "timeframe_name": "4h",
    "timeframe_id": 1914,
    "open_time": 1639699200000,
    "open": 1.1,
    "high": 1.2,
    "low": 1.3,
    "close": 1.4,
    "close_time": 1639713599999,
    "candle_id": 1
  }
]

client.ft(candles_index).info():
{'index_name': 'candles', 'index_options': [], 'index_definition': [b'key_type', b'JSON', b'prefixes', [b'candles'], b'default_score', b'1'], 'attributes': [[b'identifier', b'$..stream_name', b'attribute', b'stream_name', b'type', b'TEXT', b'WEIGHT', b'1'], [b'identifier', b'$..symbol_name', b'attribute', b'symbol_name', b'type', b'TEXT', b'WEIGHT', b'1'], [b'identifier', b'$..timeframe_name', b'attribute', b'timeframe_name', b'type', b'TEXT', b'WEIGHT', b'1']], 'num_docs': '1', 'max_doc_id': '2', 'num_terms': '3', 'num_records': '3', 'inverted_sz_mb': '1.811981201171875e-05', 'total_inverted_index_blocks': '3', 'offset_vectors_sz_mb': '3.814697265625e-06', 'doc_table_size_mb': '8.487701416015625e-05', 'sortable_values_size_mb': '0', 'key_table_size_mb': '2.765655517578125e-05', 'records_per_doc_avg': '3', 'bytes_per_record_avg': '6.3333334922790527', 'offsets_per_term_avg': '1.3333333730697632', 'offset_bits_per_record_avg': '8', 'hash_indexing_failures': '0', 'indexing': '0', 'percent_indexed': '1', 'gc_stats': [b'bytes_collected', b'0', b'total_ms_run', b'0', b'total_cycles', b'0', b'average_cycle_time_ms', b'-nan', b'last_run_time_ms', b'0', b'gc_numeric_trees_missed', b'0', b'gc_blocks_denied', b'0'], 'cursor_stats': [b'global_idle', 0, b'global_total', 0, b'index_capacity', 128, b'index_total', 0]}

client.ft(candles_index).search("*"):
Result{1 total, docs: [Document {'id': 'candles', 'payload': None, 'json': '[{"stream_name":"dogeusdt@kline_4h","symbol_name":"DOGEUSDT","symbol_id":19948,"timeframe_name":"4h","timeframe_id":1914,"open_time":1639699200000,"open":1.1,"high":1.2,"low":1.3,"close":1.4,"close_time":1639713599999,"candle_id":1}]'}]}

client.ft(candles_index).search("4h"):
Result{1 total, docs: [Document {'id': 'candles', 'payload': None, 'json': '[{"stream_name":"dogeusdt@kline_4h","symbol_name":"DOGEUSDT","symbol_id":19948,"timeframe_name":"4h","timeframe_id":1914,"open_time":1639699200000,"open":1.1,"high":1.2,"low":1.3,"close":1.4,"close_time":1639713599999,"candle_id":1}]'}]}

client.ft(candles_index).search("@timeframe_name:(4h)"):
Result{1 total, docs: [Document {'id': 'candles', 'payload': None, 'json': '[{"stream_name":"dogeusdt@kline_4h","symbol_name":"DOGEUSDT","symbol_id":19948,"timeframe_name":"4h","timeframe_id":1914,"open_time":1639699200000,"open":1.1,"high":1.2,"low":1.3,"close":1.4,"close_time":1639713599999,"candle_id":1}]'}]}
Jason
  • 404
  • 4
  • 14

1 Answers1

0

My testing was flawed, and I didn't properly test a reference that I gave to the working solution, which is:

candle_index_schema = (
    TextField('$..stream_name', as_name='stream_name'),
    TextField('$..symbol_name', as_name='symbol_name'),
    TextField('$..timeframe_name', as_name='timeframe_name'),
    )

Updated original question with answer and examples.

Jason
  • 404
  • 4
  • 14