Redisearch全文索引不适用于Python客户端

3qpi33ja  于 5个月前  发布在  Redis
关注(0)|答案(3)|浏览(62)

bounty已结束。回答此问题有资格获得+500声望赏金。赏金宽限期将在10小时后结束。NedStarkOfWinterfell正在寻找来自信誉良好的来源的答案

我试图按照this Redis文档链接创建一个小DB的显着的人在真实的时间搜索(使用Python客户端)。
我尝试了一个类似的代码,但是最后一行,用“s”查询,应该返回两个文档,而不是返回一个空白的集合。

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"))

字符串

f0brbegy

f0brbegy1#

当从redis-py客户端执行查询时,它会将FT.SEARCH命令发送到redis服务器。例如,您可以从redis-py客户端使用MONITOR命令来观察它。
根据documentation,当提供一个单词用于研究时,匹配是满的。这就是为什么你的查询结果是空集。如果你想通过前缀搜索,你需要使用表达式prefix*
然而,文件说:
前缀至少需要两个字符长。
因此,你不能只从s开始搜索单词。你可以做什么:

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}'}]}

字符串

旁白

如果要将搜索范围限定在特定字段上,则语法为:

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


其中@field_name是模式字段的名称。否则,搜索将查找所有TextField属性。

mlnl4t2r

mlnl4t2r2#

您可以尝试重新定义文档d1d2d3。JSON中存在语法错误
在下面的代码中,我纠正了“pl”字段的JSON字符串中的语法错误,并修复了查询字符串中的拼写错误。

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)

字符串

iswrvxsc

iswrvxsc3#

问题可能与您在中构造Query对象的方式有关您试图搜索"key"字段的值与字符串“s”匹配的文档。但是,由于“key”字段的类型为TextField,因此它不会对术语"s"执行全文搜索,而是会查找完全匹配的字段
因此,如果要在"key"字段上执行full-text搜索,则应使用TextFiel搜索功能

import redis
from redis.commands.json.path import Path
from redis.commands.search.field import TextField, NumericField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.query import 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)

# Use TextField with wildcard for partial matching on the "key" field
rs.search(Query("@key:s*"))

字符串

相关问题