如何从 Redis 获取一组特定的键
How to get a specific set of keys from Redis
我有一份 keys
的列表,我想从 Redis
中获取。我写了一个这样的函数,但它 return 包含所有内容:
public IOrderedEnumerable<Fields> GetValues(List<string> symbols)
{
var retVal = new List<Fields>();
var patternStr = "[";
int count = 0;
foreach (var symbol in symbols)
{
patternStr += (symbol);
if (++count != symbols.Count)
{
patternStr += ", ";
}
}
patternStr += "]*";
foreach (var ep in redis.GetEndPoints())
{
var server = redis.GetServer(ep);
var keysList = server.Keys(database: 0, pattern: patternStr).ToList();
var keys = keysList.ToArray();
Console.WriteLine("Number of Symbols in this range{0} ", keys.Length);
foreach (var rk in keys)
{
var myValTask = db.StringGetAsync(rk.ToString());
var myVal = myValTask.Result;
var jsonStr = myVal.ToString();
...
}
...
}
...
我认为这部分代码有问题。我只想要 Redis
到 return subset
的 keys
,并且我正在通过用“,”分隔它们来构建一个模式:
var patternStr = "[";
int count = 0;
foreach (var symbol in symbols)
{
patternStr += (symbol);
if (++count != symbols.Count)
{
patternStr += ", ";
}
}
patternStr += "]*";
我知道我可以获取所有密钥,然后在获取后对其进行过滤,但我想避免网络抖动...
编辑 1
顺便说一句,按键看起来像这样:
127.0.0.1:6379> keys *
1) "BBWI_2022-08-19"
2) "ABBV_2023-01-20"
3) "ZTS_2022-10-21"
如果我没理解错的话,你有一组离散的键,你想在一个批次中获取。如果是这样,您可以通过传递 RedisKey[]
array to StringGetAsync
:
来获取所有项目(在合理范围内,一次说 < 1000)
var keys = symbols.Select(symbol => (RedisKey)symbol).ToArray();
var values = await db.StringGetAsync(keys);
// .. use values
你可以像这样在redis服务器上使用Scan
命令:
public async Task<List<string>> ScanKeysAsync(string match, string count)
{
var schemas=new List<string>();
int nextCursor = 0;
do
{
RedisResult redisResult =await _redisServer.ExecuteAsync("SCAN", nextCursor.ToString(), "MATCH", match, "COUNT", count);
var innerResult = (RedisResult[])redisResult;
nextCursor = int.Parse((string)innerResult[0]);
List<string> resultLines = ((string[])innerResult[1]).ToList();
schemas.AddRange(resultLines);
}
while (nextCursor != 0);
return schemas;
}
在你的情况下是这样的:
var keys=await ScanKeysAsync("BBWI*",10);//return max 10 occurance of pattern
但我建议在非常特殊的情况下使用Scan
,因为它充当游标并会在redis中的所有键之间迭代以找到匹配项,另请阅读此https://redis.io/commands/scan
测试
var redis = scope.ServiceProvider.GetRequiredService<IDatabase>();
await redis.StringSetAsync("BBWI_2022-08-19", "test1",TimeSpan.FromMinutes(5));
await redis.StringSetAsync("BBWI_20fd22-08-19", "test2", TimeSpan.FromMinutes(5));
await redis.StringSetAsync("ABBV_2023-08-19", "test3", TimeSpan.FromMinutes(5));
var foundKeys = await ScanKeysAsync("BBW*", "10");
//BBWI_2022-08-19
//BBWI_20fd22-08-19
我有一份 keys
的列表,我想从 Redis
中获取。我写了一个这样的函数,但它 return 包含所有内容:
public IOrderedEnumerable<Fields> GetValues(List<string> symbols)
{
var retVal = new List<Fields>();
var patternStr = "[";
int count = 0;
foreach (var symbol in symbols)
{
patternStr += (symbol);
if (++count != symbols.Count)
{
patternStr += ", ";
}
}
patternStr += "]*";
foreach (var ep in redis.GetEndPoints())
{
var server = redis.GetServer(ep);
var keysList = server.Keys(database: 0, pattern: patternStr).ToList();
var keys = keysList.ToArray();
Console.WriteLine("Number of Symbols in this range{0} ", keys.Length);
foreach (var rk in keys)
{
var myValTask = db.StringGetAsync(rk.ToString());
var myVal = myValTask.Result;
var jsonStr = myVal.ToString();
...
}
...
}
...
我认为这部分代码有问题。我只想要 Redis
到 return subset
的 keys
,并且我正在通过用“,”分隔它们来构建一个模式:
var patternStr = "[";
int count = 0;
foreach (var symbol in symbols)
{
patternStr += (symbol);
if (++count != symbols.Count)
{
patternStr += ", ";
}
}
patternStr += "]*";
我知道我可以获取所有密钥,然后在获取后对其进行过滤,但我想避免网络抖动...
编辑 1
顺便说一句,按键看起来像这样:
127.0.0.1:6379> keys *
1) "BBWI_2022-08-19"
2) "ABBV_2023-01-20"
3) "ZTS_2022-10-21"
如果我没理解错的话,你有一组离散的键,你想在一个批次中获取。如果是这样,您可以通过传递 RedisKey[]
array to StringGetAsync
:
var keys = symbols.Select(symbol => (RedisKey)symbol).ToArray();
var values = await db.StringGetAsync(keys);
// .. use values
你可以像这样在redis服务器上使用Scan
命令:
public async Task<List<string>> ScanKeysAsync(string match, string count)
{
var schemas=new List<string>();
int nextCursor = 0;
do
{
RedisResult redisResult =await _redisServer.ExecuteAsync("SCAN", nextCursor.ToString(), "MATCH", match, "COUNT", count);
var innerResult = (RedisResult[])redisResult;
nextCursor = int.Parse((string)innerResult[0]);
List<string> resultLines = ((string[])innerResult[1]).ToList();
schemas.AddRange(resultLines);
}
while (nextCursor != 0);
return schemas;
}
在你的情况下是这样的:
var keys=await ScanKeysAsync("BBWI*",10);//return max 10 occurance of pattern
但我建议在非常特殊的情况下使用Scan
,因为它充当游标并会在redis中的所有键之间迭代以找到匹配项,另请阅读此https://redis.io/commands/scan
测试
var redis = scope.ServiceProvider.GetRequiredService<IDatabase>();
await redis.StringSetAsync("BBWI_2022-08-19", "test1",TimeSpan.FromMinutes(5));
await redis.StringSetAsync("BBWI_20fd22-08-19", "test2", TimeSpan.FromMinutes(5));
await redis.StringSetAsync("ABBV_2023-08-19", "test3", TimeSpan.FromMinutes(5));
var foundKeys = await ScanKeysAsync("BBW*", "10");
//BBWI_2022-08-19
//BBWI_20fd22-08-19