Първо:
- Уверете се, че сте деактивирали функциите, които няма да използвате (
NOOFFSETS
,NOHL
,NOFREQS
,STOPWORDS 0
) - Използвайте
SORTABLE
за вашияNUMERIC
score
.
Ето схемата, която използвах за тестване:
FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0
SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE
Искате да помислите за FT.AGGREGATE
като тръбопровод.
Първата стъпка ще бъде да сортираме продуктите по @score, така че по-късно, по-надолу в процеса, когато REDUCE TOLIST 1 @product_name
, списъкът излиза сортиран:
SORTBY 2 @score DESC
Мисля, че вече правите LOAD
/APPLY
за да се справите с таговете, като TAG
полетата в противен случай биха били групирани от пълния списък с етикети, разделени със запетая, за всеки продукт. Вижте Разрешаване на GROUPBY при проблем с полетата на маркера. Така че следващата ни стъпка е в процес на изпълнение е:
LOAD 1 @tags
APPLY split(@tags) as TAG
След това групираме по @TAG и прилагаме двете намаления. Списъкът ни с продукти ще излезе подреден.
GROUPBY 1 @TAG
REDUCE SUM 1 @score AS total_score
REDUCE TOLIST 1 @product_name AS products
Накрая сортираме по @total_score
:
SORTBY 2 @total_score DESC
Ето последен изглед на командата:
FT.AGGREGATE product_tags *
SORTBY 2 @score DESC
LOAD 1 @tags
APPLY split(@tags) as TAG
GROUPBY 1 @TAG
REDUCE SUM 1 @score AS total_score
REDUCE TOLIST 1 @product_name AS products
SORTBY 2 @total_score DESC
Ето пълен списък с команди за илюстриране на резултата. Използвах productXX
с резултат XX
лесно да проверите визуално сортирането на продуктите.
> FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0 SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE
OK
> FT.ADD product_tags pt:product10 1 FIELDS product_name product10 tags tag2,tag3,tag4 score 10
OK
> FT.ADD product_tags pt:product1 1 FIELDS product_name product1 tags tag1,tag2,tag3 score 1
OK
> FT.ADD product_tags pt:product100 1 FIELDS product_name product100 tags tag2,tag3 score 100
OK
> FT.ADD product_tags pt:product5 1 FIELDS product_name product5 tags tag1,tag4 score 5
OK
> FT.SEARCH product_tags *
1) (integer) 4
2) "pt:product5"
3) 1) "product_name"
2) "product5"
3) "tags"
4) "tag1,tag4"
5) "score"
6) "5"
4) "pt:product100"
5) 1) "product_name"
2) "product100"
3) "tags"
4) "tag2,tag3"
5) "score"
6) "100"
6) "pt:product1"
7) 1) "product_name"
2) "product1"
3) "tags"
4) "tag1,tag2,tag3"
5) "score"
6) "1"
8) "pt:product10"
9) 1) "product_name"
2) "product10"
3) "tags"
4) "tag2,tag3,tag4"
5) "score"
6) "10"
> FT.AGGREGATE product_tags * SORTBY 2 @score DESC LOAD 1 @tags APPLY split(@tags) as TAG GROUPBY 1 @TAG REDUCE SUM 1 @score AS total_score REDUCE TOLIST 1 @product_name AS products SORTBY 2 @total_score DESC
1) (integer) 4
2) 1) "TAG"
2) "tag2"
3) "total_score"
4) "111"
5) "products"
6) 1) "product100"
2) "product10"
3) "product1"
3) 1) "TAG"
2) "tag3"
3) "total_score"
4) "111"
5) "products"
6) 1) "product100"
2) "product10"
3) "product1"
4) 1) "TAG"
2) "tag4"
3) "total_score"
4) "15"
5) "products"
6) 1) "product10"
2) "product5"
5) 1) "TAG"
2) "tag1"
3) "total_score"
4) "6"
5) "products"
6) 1) "product5"
2) "product1"
Получавате пълния списък с продукти, сортирани, а не само първите 5. По отношение на сложността няма разлика, ние платихме цената. Въздействието е в буферирането, полезния товар на мрежата и вашия клиент.
Можете да ограничите до топ 5 с помощта на Lua скрипт:
eval "local arr = redis.call('FT.AGGREGATE', KEYS[1], '*', 'SORTBY', '2', '@score', 'DESC', 'LOAD', '1', '@tags', 'APPLY', 'split(@tags)', 'as', 'TAG', 'GROUPBY', '1', '@TAG', 'REDUCE', 'SUM', '1', '@score', 'AS', 'total_score', 'REDUCE', 'TOLIST', '1', '@product_name', 'AS', 'products', 'SORTBY', '2', '@total_score', 'DESC') \n for i=2,(arr[1]+1) do \n arr[i][6] = {unpack(arr[i][6], 1, ARGV[1])} \n end \n return arr" 1 product_tags 5
Ето приятелски изглед на скрипта на Lua по-горе:
local arr = redis.call('FT.AGGREGATE', KEYS[1], ..., 'DESC')
for i=2,(arr[1]+1) do
arr[i][6] = {unpack(arr[i][6], 1, ARGV[1])}
end
return arr
Предаваме един ключ (индекса) и един аргумент (ограничението за най-добрите продукти, 5 във вашия случай):1 product_tags 3
.
С това ограничихме въздействието само до буфериране, запазено полезно натоварване на мрежата и натоварване на вашия клиент.