Pertama:
- Pastikan untuk menonaktifkan fitur yang tidak akan Anda gunakan (
NOOFFSETS
,NOHL
,NOFREQS
,STOPWORDS 0
) - Gunakan
SORTABLE
untukNUMERIC
. Andascore
.
Berikut adalah skema yang saya gunakan untuk menguji:
FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0
SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE
Anda ingin memikirkan FT.AGGREGATE
sebagai saluran.
Langkah pertama adalah mengurutkan produk berdasarkan @score, sehingga nanti, di jalur pipa, saat kita REDUCE TOLIST 1 @product_name
, daftar keluar diurutkan:
SORTBY 2 @score DESC
Saya pikir Anda sudah melakukan LOAD
/APPLY
untuk menangani tag, sebagai TAG
jika tidak, bidang akan dikelompokkan menurut daftar tag string yang dipisahkan koma, per produk. Lihat Izinkan GROUPBY pada masalah bidang tag. Jadi langkah kita selanjutnya adalah:
LOAD 1 @tags
APPLY split(@tags) as TAG
Kami kemudian mengelompokkan berdasarkan @TAG, dan menerapkan dua pengurangan. Daftar produk kami akan diurutkan.
GROUPBY 1 @TAG
REDUCE SUM 1 @score AS total_score
REDUCE TOLIST 1 @product_name AS products
Terakhir, kami mengurutkan berdasarkan @total_score
:
SORTBY 2 @total_score DESC
Berikut tampilan akhir dari perintah:
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
Berikut daftar lengkap perintah untuk mengilustrasikan hasilnya. Saya menggunakan productXX
dengan skor XX
untuk memverifikasi penyortiran produk secara visual dengan mudah.
> 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"
Anda mendapatkan daftar lengkap produk yang diurutkan, bukan hanya 5 teratas. Dari segi kerumitan tidak ada bedanya, kami membayar harganya. Dampaknya ada di buffering, payload jaringan, dan klien Anda.
Anda dapat membatasi hingga 5 teratas menggunakan skrip 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
Berikut tampilan ramah dari skrip Lua di atas:
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
Kami melewati satu kunci (indeks) dan satu argumen (batas untuk produk teratas, 5 dalam kasus Anda):1 product_tags 3
.
Dengan ini, kami membatasi dampaknya hanya pada buffering, menghemat muatan jaringan, dan memuat pada klien Anda.