skip to Main Content

I am trying to follow this Redis documentation link to create a small DB of notable people searchable in real time (using Python client).

I tried a similar code, but the final line, which queries by "s", should return two documents, instead, it returns a blank set. Can anybody help me find out the mistake I am making?

import redis
from redis.commands.json.path import Path
import redis.commands.search.aggregation as aggregations
import redis.commands.search.reducers as reducers
from redis.commands.search.field import TextField, NumericField, TagField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.query import NumericFilter, Query

d1 = {"key": "shahrukh khan", "pl": '{"d": "mvtv", "id": "1234-a", "img": "foo.jpg", "t: "act", "tme": "1965-"}', "org": "1", "p": 100}
d2 = {"key": "salman khan", "pl": '{"d": "mvtv", "id": "1236-a", "img": "fool.jpg", "t: "act", "tme": "1965-"}', "org": "1", "p": 100}
d3 = {"key": "aamir khan", "pl": '{"d": "mvtv", "id": "1237-a", "img": "fooler.jpg", "t: "act", "tme": "1965-"}', "org": "1", "p": 100}


schema = ( 
    TextField("$.key", as_name="key"),  
    NumericField("$.p", as_name="p"),  
) 

r = redis.Redis(host='localhost', port=6379)
rs = r.ft("idx:au") 
rs.create_index(     
    schema,     
    definition=IndexDefinition(     
        prefix=["au:"], index_type=IndexType.JSON   
    )    
)

r.json().set("au:mvtv-1234-a", Path.root_path(), d1)  
r.json().set("au:mvtv-1236-a", Path.root_path(), d2)  
r.json().set("au:mvtv-1237-a", Path.root_path(), d3)  

rs.search(Query("s"))

2

Answers


  1. you can try redefine the documents d1, d2, and d3. There are syntax errors in the JSON

    On Following code. I corrected the syntax errors in the JSON strings of the "pl" field and fixed the typo in the query string.

    d1 = {"key": "shahrukh khan", "pl": '{"d": "mvtv", "id": "1234-a", "img": "foo.jpg", "t": "act", "tme": "1965-"}', "org": "1", "p": 100}
    d2 = {"key": "salman khan", "pl": '{"d": "mvtv", "id": "1236-a", "img": "fool.jpg", "t": "act", "tme": "1965-"}', "org": "1", "p": 100}
    d3 = {"key": "aamir khan", "pl": '{"d": "mvtv", "id": "1237-a", "img": "fooler.jpg", "t": "act", "tme": "1965-"}', "org": "1", "p": 100}
    
    
    schema = ( 
        TextField("$.key", as_name="key"),  
        NumericField("$.p", as_name="p"),  
    ) 
    
    r = redis.Redis(host='localhost', port=6379)
    rs = r.ft("idx:au") 
    rs.create_index(     
        schema,     
        definition=IndexDefinition(     
            prefix=["au:"], index_type=IndexType.JSON   
        )    
    )
    
    r.json().set("au:mvtv-1234-a", Path.root_path(), d1)  
    r.json().set("au:mvtv-1236-a", Path.root_path(), d2)  
    r.json().set("au:mvtv-1237-a", Path.root_path(), d3)  
    
    Login or Signup to reply.
  2. When executing a query from the redis-py client, it will transmit the FT.SEARCH command to the redis server. You can observe it by using the command MONITOR from a redis-client for example.

    According to the documentation, when providing a single word for the research, the matching is full. That’s why the result of your query is the empty set. If you want to search by prefix, you need to use the expression prefix*.

    However, documentation says:

    The prefix needs to be at least two characters long.

    Hence, you cannot search by word starting only by s. What you could do:

    rs.search(Query("sa*"))
    #Result{1 total, docs: [Document {'id': 'au:mvtv-1236-a', 'payload': None, 'json': '{"key":"salman khan","pl":"{\"d\": \"mvtv\", \"id\": \"1236-a\", \"img\": \"fool.jpg\", \"t: \"act\", \"tme\": \"1965-\"}","org":"1","p":100}'}]}
    

    Aside note

    If you want to scope your search on a specific field, the syntax is:

    Query("@field_name: word") # Query("@key: sa*")
    

    where @field_name is the schema field’s name. Otherwise, the search will look up for all TextField attributes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search