1

As per some suggestions, I am using Redis' ZADD through BookSleeve's SortedSets.Add() to save data in a chronological order as follows:

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

Using ServiceStack's AdminUI, I can see the values tucked away in Redis.

The values are stored as UTC, and I would now like to be able to get return a range of values.

Simply, since I saved the values recently, I tried:

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

In VS, the collection contains the double value, and the Key which is of type Byte[]. I assume this is the byte array of the data saved - even though I saved it as string?

I have reviewed some code here and would like to know if there extensive documentation and some samples on how to use this function?

Community
  • 1
  • 1
ElHaix
  • 12,846
  • 27
  • 115
  • 203
  • 2
    Booksleeve acts basically as a shim directly on top of the [underlying ZRANGE command](http://redis.io/commands/zrange); btw the most direct tests link is [here](https://code.google.com/p/booksleeve/source/browse/Tests/SortedSets.cs). The `byte[]` coming back is just UTF-8 encoded - there is also `RangeString` which does the translation for you. I have to go and get food "now", but I can come back later to add a more complete example. Can you clarify: what is the issue currently? are you not getting the expected rows? or is it simply a case of switching to `RangeString`? how can I help? – Marc Gravell Feb 21 '13 at 01:57
  • Reading the ZRANGE documentation, I see that the start/stop values are zero-based beginning to end of the given range. So when I'm using RangeString() I use 0, 99999 (as no out of range exceptions are thrown) I would expect the full range of items. However, I consistently get "The method or operation is not implemented" error" . Also, not using the score doesn't help me in this case (as the score is the timestamp) and I use this for range gets. – ElHaix Feb 21 '13 at 14:41
  • that's interesting, and there was no way I could have deduced that from the question! Is there a stacktrace for that? I'm going to spin up a quick test to see if I can repro that with your code – Marc Gravell Feb 21 '13 at 15:05

1 Answers1

0

The interesting thing I noticed in this is that RangeString, which should be ideal for your scenario, lacks the offset parameter; I will rectify that - but for now, we can use Range and decode the key manually (redis allows binary keys; they do not need to be strings); the following, however, passes successfully:

[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));
    }
}

I certainly don't get a MethodNotImplementedException. I should state: I'm testing against the current "head", simply because that is what I have available.


For info: in my local copy I've implemented RangeString with offset/count, so the following passes:

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);
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I added String.Format("urn:{0}", thisChannel) - thus a fully qualified key. – ElHaix Feb 21 '13 at 16:57
  • @ElHaix a key is a key is a key; redis doesn't care what the contents are. I changed my key with `string.Format` - it still works fine. Can you show me a repro of the problem you are having? Incidentally: I see absolutely no benefit adding a `"urn:"` prefix here... – Marc Gravell Feb 21 '13 at 17:49