2019独角兽企业重金招聘Python工程师标准>>>
算法:
容器使用的是zset,因为当zset中所有的分值都为0时集合将按ascii码排序。所以利用这点只要找出其范围再
使用zrange获取就行了。取得该范围的方式是通过在集合中插入两个搜索关键字的临界值,如搜索abc,那么这个
临界值为abb{ 和abc{ 。将其插入到集合中再搜索出基位置。最后将其删除(参考:<
下面是分页lua脚本:
--[[
zset 分页查询:
格式:
参数说明:{
zsetKey :有序集键 key1
searchKey : 查询内容 argv1
pageNo :当前页号(默认为1) argv2
pageSize :页面大小(默认为15) argv3
}
示例: evalsha 232fd51614574cf0867b83d384a5e898cfd24e5a 1 my:zset abc
]]
local zsetKey,searchKey,pageNo,pageSize = KEYS[1],ARGV[1],tonumber(ARGV[2]),tonumber(ARGV[3])
local content = ",-/0123456789@_abcdefghijklmnopqrstuvwxyz{"
if(not zsetKey) then return {} end
if(not pageNo or pageNo < 1) then pageNo = 1 end
if(not pageSize or pageSize < 1) then pageSize = 15 end
local recTotal = redis.call('zcard',zsetKey)
if(recTotal == 0) then return {} end --空集合
--找出查询关键字在zset中的位置
local function getRange(searchKey)
local lastChar = string.sub(searchKey,-1,-1)
local temp = string.find(content,lastChar)-1
local startStr = string.sub(searchKey,1,-2)..string.sub(content,temp,temp)..string.sub(content,-1,-1)
local endStr = searchKey..string.sub(content,-1,-1)
redis.call('zadd',zsetKey,0,startStr)
redis.call('zadd',zsetKey,0,endStr)
local starp1,starp2 = redis.call('zrank',zsetKey,startStr) , redis.call('zrank',zsetKey,endStr)
redis.call('zrem',zsetKey,startStr)
redis.call('zrem',zsetKey,endStr)
return starp1,starp2-2
end
local startPosition,endPosition = 0,recTotal
if(searchKey ~= "") then
startPosition,endPosition = getRange(searchKey);
end
startPosition = startPosition + (pageNo-1)*pageSize
endPosition = math.min(startPosition + pageSize-1,endPosition)
if(startPosition > recTotal or endPosition < 0) then return {} end --没有找到要查询的结果
return redis.call('zrange',zsetKey,startPosition,endPosition)
--[[
zset 查询总数:
格式:
参数说明:{
zsetKey :有序集键 key1
searchKey : 查询内容 argv1
}
示例: evalsha 232fd51614574cf0867b83d384a5e898cfd24e5a 1 my:zset abc
]]
local zsetKey,searchKey = KEYS[1],ARGV[1]
local content = ",-/0123456789@_abcdefghijklmnopqrstuvwxyz{"
if(not zsetKey) then return 0 end
local recTotal = redis.call('zcard',zsetKey)
if(searchKey == "") then return recTotal end
--找出查询关键字在zset中的位置
local function getRange(searchKey)
local lastChar = string.sub(searchKey,-1,-1)
local temp = string.find(content,lastChar)-1
local startStr = string.sub(searchKey,1,-2)..string.sub(content,temp,temp)..string.sub(content,-1,-1)
local endStr = searchKey..string.sub(content,-1,-1)
redis.call('zadd',zsetKey,0,startStr)
redis.call('zadd',zsetKey,0,endStr)
local starp1,starp2 = redis.call('zrank',zsetKey,startStr) , redis.call('zrank',zsetKey,endStr)
redis.call('zrem',zsetKey,startStr)
redis.call('zrem',zsetKey,endStr)
return starp1,starp2-2
end
local startPosition,endPosition = getRange(searchKey);
if(startPosition > recTotal or endPosition < 0) then return 0 end --没有找到要查询的结果
return endPosition - startPosition + 1;
上面只支持英文查询(小写)