from redis.commands.search.query import Query
from redis.commands.search.field import TextField, NumericField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.aggregation import AggregateRequest, Asc, Desc
import redis
client = redis.Redis(
host=redis_host,
port=redis_port,
password=redis_password,
decode_responses=True,
)
index_name = 'idx:flowers'
index = client.ft(index_name)
# check if index exists if not then create
try:
index.info()
except:
schema = (
TextField('name', weight=0.7), # textfields can also be sortable
TextField('type'),
NumericField('length', sortable=True), # numericfields cannot have weights
NumericField('rating', sortable=True),
)
# index creation.
# using IndexDefinition(prefix= will index automagically all redis keys that have this prefix
client.ft(index_name).create_index(schema, definition=IndexDefinition(prefix=['flower:']))
# since the index is new we need to load the data (if it does not exist on redis already)
flowers = [
{'name': 'gladiola', 'type': 'cactus', 'length': 22, 'rating': 3.57, 'color': 'violet'},
{'name': 'eleanor', 'type': 'cactus,pine', 'length': 15, 'rating': 4.34, 'color': 'brown'},
{'name': 'loveme', 'type': 'berry', 'length': 13, 'rating': 5, 'color': 'blue'},
]
for i, flower in enumerate(flowers):
pipe = client.pipeline()
pipe.hset(name='flower:' + str(i), key='name', value=flower['name'])
pipe.hset(name='flower:' + str(i), key='type', value=flower['type'])
pipe.hset(name='flower:' + str(i), key='length', value=flower['length'])
pipe.hset(name='flower:' + str(i), key='rating', value=flower['rating'])
pipe.hset(name='flower:' + str(i), key='color', value=flower['color'])
pipe.execute()
所有这些散列都将被索引,因为它们的键具有前缀'flower:' 搜索:
# first we need to get the index we are going to work with
index = client.ft(index_name)
# wildcard search from both sides on all searchable fields
results = index.search(Query('*actu*'))
results = results.docs
for result in results:
print(result.__dict__)
# sort by a sortable field in ascending order (you can sort by a non-sortable field but it will be slower)
results = index.search(Query('*actu*').sort_by(field='length', asc=True))
# pagination. 'num' is size of the page
results = index.search(Query('*actu*').paging(offset=0, num=10))
# search a specific field
results = index.search(Query('@name:*actu*'))
# search specific fields - OR operation
results = index.search(Query('@name|type:*actu*'))
# search specific fields - AND operation
results = index.search(Query('@name:*actu* @type:*actu*'))
# sort by multiple fields - length and rating. We need to use Aggregation to achieve this
request = AggregateRequest(
query='@name|type:*actu*'
).sort_by(
Asc('@length'),
Desc('@rating'),
).limit( # pagination
0, 10
).load( # we need to indicate the fields we want to get in results
'@name',
'@type',
'@length',
'@rating',
'@color',
)
# perform aggregate search
results = index.aggregate(request)
print(results.rows)
1条答案
按热度按时间iyfjxgzm1#
张贴答案。我花了相当长的时间来弄清楚所有这些,所以希望它会为你们中的一些人节省保存时间。Redisearch确实是一项令人惊叹的技术,值得许多人使用。
首先,你必须创建一个索引来使用redisearch:
所有这些散列都将被索引,因为它们的键具有前缀'flower:'
搜索:
指出错误和改进,我很乐意编辑答案。