优化RedisGeo,返回数组时不允许null,而是空数组

This commit is contained in:
智能大石头 2025-05-05 08:29:08 +08:00
parent e0d0ff20c7
commit 1891c09638
3 changed files with 22 additions and 35 deletions

View File

@ -3,8 +3,8 @@
/// <summary>超级基数估算</summary>
/// <remarks>
/// HyperLogLog可以使用固定且很少的内存每个HyperLogLog结构需要12K字节再加上key本身的几个字节来存储集合的唯一元素。
/// 返回的可见集合基数并不是精确值, 而是一个带有 0.81% 标准错误standard error的近似值。
/// 例如为了记录一天会执行多少次各不相同的搜索查询, 一个程序可以在每次执行搜索查询时调用一次PFADD 并通过调用PFCOUNT命令来获取这个记录的近似结果。
/// 返回的可见集合基数并不是精确值,而是一个带有 0.81% 标准错误standard error的近似值。
/// 例如为了记录一天会执行多少次各不相同的搜索查询,一个程序可以在每次执行搜索查询时调用一次PFADD并通过调用PFCOUNT命令来获取这个记录的近似结果。
/// 注意: 这个命令的一个副作用是可能会导致HyperLogLog内部被更改出于缓存的目的,它会用8字节的来记录最近一次计算得到基数,所以PFCOUNT命令在技术上是个写命令。
/// </remarks>
public class HyperLogLog : RedisBase
@ -19,7 +19,7 @@ public class HyperLogLog : RedisBase
/// <summary>添加</summary>
/// <remarks>
/// 这个命令的一个副作用是它可能会更改这个HyperLogLog的内部来反映在每添加一个唯一的对象时估计的基数(集合的基数)。
/// 如果一个HyperLogLog的估计的近似基数在执行命令过程中发了变化 PFADD 返回1否则返回0
/// 如果一个HyperLogLog的估计的近似基数在执行命令过程中发了变化PFADD 返回1否则返回0
/// 如果指定的key不存在这个命令会自动创建一个空的HyperLogLog结构指定长度和编码的字符串
/// 如果在调用该命令时仅提供变量名而不指定元素也是可以的如果这个变量名存在则不会有任何操作如果不存在则会创建一个数据结构返回1
/// </remarks>
@ -36,8 +36,8 @@ public class HyperLogLog : RedisBase
/// <summary>合并</summary>
/// <remarks>
/// 将多个 HyperLogLog 合并merge为一个 HyperLogLog 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合observed set的并集。
/// 合并得出的 HyperLogLog 会被储存在目标变量(第一个参数)里面, 如果该键并不存在, 那么命令在执行之前, 会先为该键创建一个空的。
/// 将多个 HyperLogLog 合并merge为一个 HyperLogLog 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合observed set的并集。
/// 合并得出的 HyperLogLog 会被储存在目标变量(第一个参数)里面,如果该键并不存在,那么命令在执行之前,会先为该键创建一个空的。
/// </remarks>
/// <param name="keys"></param>
/// <returns></returns>

View File

@ -352,10 +352,10 @@ public class RedisClient : DisposeBase
/*
*
* 1 ++OK\r\n
* 2: - -ERR unknown command 'mush'\r\n
* 3: : :1\r\n
* 2: --ERR unknown command 'mush'\r\n
* 3: ::1\r\n
* 4512M $+ $4\r\nmush\r\n
* 5* *2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n
* 5**2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n
*/
var list = new List<Object?>();

View File

@ -55,10 +55,10 @@ public class RedisGeo : RedisBase
/// <summary>获取一批点的坐标</summary>
/// <param name="members"></param>
/// <returns></returns>
public GeoInfo[]? GetPosition(params String[] members)
public GeoInfo[] GetPosition(params String[] members)
{
var rs = Execute((rc, k) => rc.ExecuteByKey<String, Object[]>("GEOPOS", Key, members), false);
if (rs == null || rs.Length == 0) return null;
if (rs == null || rs.Length == 0) return [];
var list = new List<GeoInfo>();
for (var i = 0; i < rs.Length; i++)
@ -94,22 +94,27 @@ public class RedisGeo : RedisBase
/// <returns></returns>
public String[]? GetHash(params String[] members) => Execute((rc, k) => rc.ExecuteByKey<String, String[]>("GEOHASH", Key, members), false);
/// <summary>以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素</summary>
/// <summary>以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素</summary>
/// <param name="longitude"></param>
/// <param name="latitude"></param>
/// <param name="radius"></param>
/// <param name="unit"></param>
/// <param name="count"></param>
/// <returns></returns>
public GeoInfo[]? GetRadius(Double longitude, Double latitude, Double radius, String? unit = null, Int32 count = 0)
public GeoInfo[] GetRadius(Double longitude, Double latitude, Double radius, String? unit = null, Int32 count = 0)
{
if (unit.IsNullOrEmpty()) unit = "m";
var rs = count > 0 ?
Execute((rc, k) => rc.Execute<Object[]>("GEORADIUS", Key, longitude, latitude, radius, unit, "WITHDIST", "WITHCOORD", "ASC", "COUNT", count), false) :
Execute((rc, k) => rc.Execute<Object[]>("GEORADIUS", Key, longitude, latitude, radius, unit, "WITHDIST", "WITHCOORD", "ASC"), false);
if (rs == null || rs.Length == 0) return null;
if (rs == null || rs.Length == 0) return [];
return Parse(rs);
}
private GeoInfo[] Parse(Object[] rs)
{
var list = new List<GeoInfo>();
for (var i = 0; i < rs.Length; i++)
{
@ -131,39 +136,21 @@ public class RedisGeo : RedisBase
return list.ToArray();
}
/// <summary>以给定的点位为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素</summary>
/// <summary>以给定的点位为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素</summary>
/// <param name="member"></param>
/// <param name="radius"></param>
/// <param name="unit"></param>
/// <param name="count"></param>
/// <returns></returns>
public GeoInfo[]? GetRadius(String member, Double radius, String? unit = null, Int32 count = 0)
public GeoInfo[] GetRadius(String member, Double radius, String? unit = null, Int32 count = 0)
{
if (unit.IsNullOrEmpty()) unit = "m";
var rs = count > 0 ?
Execute((rc, k) => rc.Execute<Object[]>("GEORADIUSBYMEMBER", Key, member, radius, unit, "WITHDIST", "WITHCOORD", "ASC", "COUNT", count), false) :
Execute((rc, k) => rc.Execute<Object[]>("GEORADIUSBYMEMBER", Key, member, radius, unit, "WITHDIST", "WITHCOORD", "ASC"), false);
if (rs == null || rs.Length == 0) return null;
if (rs == null || rs.Length == 0) return [];
var list = new List<GeoInfo>();
for (var i = 0; i < rs.Length; i++)
{
var inf = new GeoInfo();
if (rs[i] is Object[] vs)
{
inf.Name = (vs[0] as IPacket)?.ToStr();
inf.Distance = (vs[1] as IPacket)?.ToStr().ToDouble() ?? 0;
if (vs[2] is Object[] vs2)
{
inf.Longitude = (vs2[0] as IPacket)?.ToStr().ToDouble() ?? 0;
inf.Latitude = (vs2[1] as IPacket)?.ToStr().ToDouble() ?? 0;
}
}
list.Add(inf);
}
return list.ToArray();
return Parse(rs);
}
}