Redis
 sql >> база данни >  >> NoSQL >> Redis

Повторно търсене на обобщено връщане на първите 5 от всяка група

Първо:

  • Уверете се, че сте деактивирали функциите, които няма да използвате (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 .

С това ограничихме въздействието само до буфериране, запазено полезно натоварване на мрежата и натоварване на вашия клиент.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Управление на връзки

  2. Производителност на Redis на многоядрен процесор

  3. Не може да се свърже с Redis от Docker

  4. Записване на HASH в Redis в приложение за rails

  5. Кеш на Azure Redis – изтичане на изчакване при GET повиквания