Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

Tìm kiếm lại tổng hợp trở lại top 5 của mỗi nhóm

Đầu tiên:

  • Đảm bảo tắt các tính năng bạn sẽ không sử dụng (NOOFFSETS , NOHL , NOFREQS , STOPWORDS 0 )
  • Sử dụng SORTABLE cho NUMERIC của bạn score .

Đây là lược đồ tôi đã sử dụng để kiểm tra:

FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0
    SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE

Bạn muốn nghĩ về FT.AGGREGATE như một đường ống dẫn.

Bước đầu tiên sẽ là sắp xếp các sản phẩm theo @score, để sau đó, trong quy trình, khi chúng tôi REDUCE TOLIST 1 @product_name , danh sách được sắp xếp:

SORTBY 2 @score DESC

Tôi nghĩ bạn đang làm LOAD / APPLY để xử lý các thẻ, dưới dạng TAG nếu không, các trường sẽ được nhóm theo danh sách thẻ chuỗi được phân tách bằng dấu phẩy đầy đủ cho mỗi sản phẩm. Xem Cho phép GROUPBY về vấn đề trường thẻ. Vì vậy, bước tiếp theo của chúng tôi trong quy trình là:

LOAD 1 @tags 
APPLY split(@tags) as TAG 

Sau đó, chúng tôi nhóm theo @TAG và áp dụng hai mức giảm. Danh sách sản phẩm của chúng tôi sẽ được sắp xếp theo thứ tự.

GROUPBY 1 @TAG
    REDUCE SUM 1 @score AS total_score
    REDUCE TOLIST 1 @product_name AS products

Cuối cùng, chúng tôi sắp xếp theo @total_score :

SORTBY 2 @total_score DESC

Đây là chế độ xem cuối cùng của lệnh:

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

Dưới đây là danh sách đầy đủ các lệnh để minh họa kết quả. Tôi đã sử dụng productXX với điểm XX để dễ dàng xác minh trực quan việc phân loại sản phẩm.

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

Bạn đang nhận được danh sách đầy đủ các sản phẩm được sắp xếp, không chỉ top 5. Sự phức tạp-khôn ngoan không tạo ra sự khác biệt, chúng tôi đã phải trả giá. Tác động là vào bộ đệm, tải trọng mạng và ứng dụng khách của bạn.

Bạn có thể giới hạn ở top 5 bằng cách sử dụng tập lệnh 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

Dưới đây là một cái nhìn thân thiện về tập lệnh Lua ở trên:

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

Chúng tôi đang chuyển một khóa (chỉ mục) và một đối số (giới hạn cho các sản phẩm hàng đầu, 5 trong trường hợp của bạn):1 product_tags 3 .

Với điều này, chúng tôi đã hạn chế tác động chỉ vào bộ đệm, lưu tải trọng mạng và tải trên ứng dụng khách của bạn.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Redis:Làm cách nào tôi có thể sắp xếp hàm băm của mình theo các phím?

  2. Cách tắt Redis Caching tại thời điểm chạy nếu kết nối redis không thành công

  3. Giao tiếp giữa hai vùng chứa Docker trên macOS 10.12

  4. Làm cách nào để tạo một bus dịch vụ dựa trên Windows cục bộ bên ngoài Azure, tương tự như Redis với tính năng tự động chuyển lỗi?

  5. Redis không chọn các sự kiện phát sóng trong Laravel 5.1