2013-01-23 16 views

Trả lời

3

Một cách để giải quyết vấn đề này là sử dụng kịch bản Lua phía máy chủ.

Hãy xem xét kịch bản sau đây:

local res = {} 
local result = {} 
local tmp = redis.call('zrange', KEYS[1], 0, -1, 'withscores') 
for i=1,#tmp,2 do 
    res[tmp[i+1]]=true 
end 
for k,_ in pairs(res) do 
    table.insert(result,k) 
end 
return result 

Bạn có thể thực hiện nó bằng cách sử dụng lệnh EVAL.

Nó sử dụng lệnh zrange để trích xuất nội dung của zset (với điểm số), sau đó nó xây dựng một bộ (được biểu diễn bằng một bảng trong Lua) để loại bỏ điểm dư thừa và cuối cùng xây dựng bảng trả lời. Vì vậy, các giá trị của zset không bao giờ được gửi qua mạng.

Kịch bản này có một lỗ hổng nếu số lượng mục trong zset thực sự cao, bởi vì nó sao chép toàn bộ zset trong đối tượng Lua (vì vậy nó có bộ nhớ). Tuy nhiên, nó rất dễ dàng để thay đổi nó để lặp lại trên zset tăng dần (20 mục cho mỗi 20 mặt hàng). Ví dụ:

local res = {} 
local result = {} 
local n = redis.call('zcard', KEYS[1]) 
local i=0 
while i<n do 
    local tmp = redis.call('zrange', KEYS[1], i, i+20, 'withscores') 
    for j=1,#tmp,2 do 
     res[tmp[j+1]]=true 
     i = i + 1 
    end 
end 
for k,_ in pairs(res) do 
    table.insert(result,k) 
end 
return result 

Xin lưu ý Tôi là tổng số người mới ở Lua, vì vậy có lẽ có nhiều cách thanh lịch hơn để đạt được điều tương tự.

7

EDIT: Do vấn đề của bạn với kích thước của các giá trị không rõ ràng trước đây, tôi đã thực hiện một số nghiên cứu bổ sung.

Có theo tài liệu hiện tại không có cách nào để chỉ lấy điểm từ một bộ được sắp xếp.

Điều bạn cần làm để có được điểm số là đồng thời thêm chúng vào một bộ riêng biệt và nhận chúng từ đó khi cần.

Điều bạn nên làm trước tiên là cố gắng ánh xạ vấn đề của bạn khác nhau thành cấu trúc dữ liệu. Tôi không thể nói từ câu hỏi của bạn tại sao bạn cần để có được điểm số, nhưng có thể có những cách khác để cấu trúc vấn đề sẽ bản đồ tốt hơn để Redis.

-

Tôi không chắc chắn có cách nào để có được tất cả các điểm mà không nhận được các phím, nhưng ZRANGE sẽ ít nhất có được thông tin bạn đang tìm kiếm;

redis> ZADD myzset 10 "one" 
(integer) 1 

redis> ZADD myzset 20 "two" 
(integer) 1 

redis> ZADD myzset 30 "three" 
(integer) 1 

redis> ZRANGE myzset 0 -1 WITHSCORES 
["one","10","two","20","three","30"] 
+0

tôi biết rằng, nhưng vấn đề là các v alues ​​là quá lớn trong trường hợp của tôi, nó là vấn đề để theo dõi chỉ có điểm số. – biztiger

+0

@biztiger Đã cập nhật. Rõ ràng không phải là giải pháp hoàn hảo, nhưng là một giải pháp khả thi nếu bạn thực sự cần chức năng. –

1

Bạn cần chuyển đối số tùy chọn WITHSCORES.Xem tài liệu here:

ZREVRANGE khởi đầu quan trọng ngăn chặn [WITHSCORES] Return một loạt các thành viên trong một bộ sắp xếp , bởi chỉ số, với điểm đặt hàng từ cao xuống thấp

0

Khi nói đến ruby ​​sau lệnh sẽ làm

redis.zrange("zset", 0, -1, :with_scores => true) 
# => [["a", 32.0], ["b", 64.0]] 

nguồn Ruby Docs

Các vấn đề liên quan