【问题标题】:The proper way to retrieve a sorted set from Redis using BookSleeve使用 BookSleeve 从 Redis 检索排序集的正确方法
【发布时间】:2013-02-21 23:28:27
【问题描述】:

根据some suggestions,我使用Redis的ZADD通过BookSleeve的SortedSets.Add()按时间顺序保存数据如下:

TimeSpan span = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)); 
_connection.SortedSets.Add(_db, thisChannel, message, span.TotalSeconds, false);

使用 ServiceStack 的 AdminUI,我可以看到隐藏在 Redis 中的值。

这些值存储为 UTC,我现在希望能够返回一系列值。

简单地说,因为我最近保存了这些值,所以我尝试了:

var subset = _connection.Wait(_connection.SortedSets.Range(_db, thisChannel, span.TotalSeconds - 10000, span.TotalSeconds, offset: 0, count: 50));

在 VS 中,集合包含双精度值和 Byte[] 类型的 Key。我假设这是保存的数据的字节数组 - 即使我将它保存为字符串?

我查看了一些代码here,想知道是否有关于如何使用此功能的大量文档和一些示例?

【问题讨论】:

  • Booksleeve 基本上作为直接位于underlying ZRANGE command 顶部的垫片;顺便说一句,最直接的测试链接是here。返回的 byte[] 只是 UTF-8 编码 - 还有 RangeString 会为您进行翻译。我必须“现在”去拿食物,但我可以稍后再回来添加一个更完整的示例。您能否澄清一下:目前的问题是什么?你没有得到预期的行吗?还是只是切换到RangeString 的情况?我能提供什么帮助?
  • 阅读 ZRANGE 文档,我看到开始/停止值是从零开始的给定范围的开始到结束。因此,当我使用 RangeString() 时,我使用 0, 99999 (因为没有抛出超出范围的异常),我希望得到所有项目。但是,我一直收到 "The method or operation is not implemented" 错误" 。此外,在这种情况下,不使用分数对我没有帮助(因为分数是时间戳),我将其用于范围获取。
  • 这很有趣,我无法从问题中推断出这一点!有堆栈跟踪吗?我将启动一个快速测试,看看我是否可以用你的代码重现它

标签: c# .net date booksleeve


【解决方案1】:

我注意到的有趣的事情是 RangeString 缺少 offset 参数,它应该是您的场景的理想选择;我将纠正这一点 - 但现在,我们可以使用 Range 并手动解码密钥(redis 允许二进制密钥;它们不需要是字符串);但是,以下内容成功通过:

[Test]
public void SO14991819()
{
    const int _db = 0;
    const string thisChannel = "SO14991819";
    const string message = "hi";
    using (var _connection = Config.GetUnsecuredConnection())
    {
        _connection.Keys.Remove(_db, thisChannel); // start from known state

        TimeSpan span = DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0));
        double val = span.TotalSeconds;

        _connection.SortedSets.Add(_db, thisChannel, message, val, false);

        var subset = _connection.Wait(_connection.SortedSets.Range(
            _db, thisChannel, span.TotalSeconds - 10000, span.TotalSeconds, offset: 0, count: 50));

        Assert.AreEqual(1, subset.Length);
        Config.AssertNearlyEqual(val, subset[0].Value);
        Assert.AreEqual(message, Encoding.UTF8.GetString(subset[0].Key));
    }
}

我当然没有MethodNotImplementedException。我应该声明:我正在针对当前的“头部”进行测试,仅仅是因为那是我可用的。


供参考:在我的本地副本中,我已经使用偏移量/计数实现了RangeString,因此以下通过:

var subset = _connection.Wait(_connection.SortedSets.RangeString(
    _db, thisChannel, span.TotalSeconds - 10000, span.TotalSeconds, offset: 0, count: 50));

Assert.AreEqual(1, subset.Length);
Config.AssertNearlyEqual(val, subset[0].Value);
Assert.AreEqual(message, subset[0].Key);

【讨论】:

  • 我添加了 String.Format("urn:{0}", thisChannel) - 因此是一个完全限定的键。
  • @ElHaix 键是键是键; redis 不关心内容是什么。我用string.Format 更改了我的密钥 - 它仍然可以正常工作。你能告诉我你遇到的问题的重现吗?顺便说一句:我认为在这里添加 "urn:" 前缀绝对没有任何好处......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 2013-09-08
相关资源
最近更新 更多