Redis StackExchange SortedSetAdd не обновляет существующий элемент

Я только начал изучать Redis, и когда я программирую на C#, я использую StackExchange Redis. Я хотел попробовать SortedSet, и вот простой код, который у меня есть:

Создать образец данных

  private List<User> SeedUsers() {
        var list = new List<User> {
            new User {Id = 1.ToString(), UserName = "Test1", Score = 10},
            new User {Id = 2.ToString(), UserName = "Test2", Score = 23},
            new User {Id = 3.ToString(), UserName = "Test3", Score = 15},
            new User {Id = 4.ToString(), UserName = "Test4", Score = 250},
            new User {Id = 5.ToString(), UserName = "Test5", Score = 100},
            new User {Id = 6.ToString(), UserName = "Test5", Score = 23},
            ......
        };
        return list;
    }

Добавьте данные в Redis

 public bool AddUsersToLeaderBoard() {
        var db = Connection.GetDatabase();
        var list = SeedUsers();
        var numOfSuccesses = 0;

        foreach (var item in list) {
            var r = db.SortedSetAdd("test", JsonConvert.SerializeObject(item), item.Score);
            if (r) numOfSuccesses++;
        }

        var i = list[3];
        i.Score = 888;
        db.SortedSetAdd("test", JsonConvert.SerializeObject(i), i.Score);
        return numOfSuccesses == list.Count;
    }

Что меня смущает, так это часть после цикла foreach, где я меняю 4-й элемент списка, а затем добавляю его в отсортированный набор, но он просто добавляется дважды, т.е. он не обновляется в Redis.

Я неправильно понял эту часть документации Redis?

Последнее замечание об отсортированных множествах перед тем, как перейти к следующей теме. Оценки отсортированных наборов могут быть обновлены в любое время. Простой вызов ZADD для элемента, уже включенного в отсортированный набор, обновит его оценку (и позицию) с временной сложностью O (log (N)). Таким образом, отсортированные наборы подходят, когда есть множество обновлений.

Также, чтобы убедиться, что с сериализацией JSON нет проблем, я попробовал эту строку кода:

 var x = db.SortedSetRank("test", JsonConvert.SerializeObject(list[4]), Order.Descending);

Что дало ожидаемые результаты. Так что я делаю неправильно?


person hyperN    schedule 09.09.2015    source источник


Ответы (1)


Это не тот же объект, вы обновили его оценку, прежде чем отправить его в Redis. Вместо этого сделайте так:

public bool AddUsersToLeaderBoard() {
    var db = Connection.GetDatabase();
    var list = SeedUsers();
    var numOfSuccesses = 0;

    foreach (var item in list) {
        var r = db.SortedSetAdd("test", JsonConvert.SerializeObject(item), item.Score);
        if (r) numOfSuccesses++;
    }

    var i = list[3];
    //i.Score = 888; - this line can be removed
    db.SortedSetAdd("test", JsonConvert.SerializeObject(i), 888);
    return numOfSuccesses == list.Count;
}

И вывод zrange будет ожидаемым (с Test4 только один раз и реальным счетом 888):

127.0.0.1:6379> zrange test 0 -1 withscores
1) "{\"Id\":\"1\",\"Score\":10,\"UserName\":\"Test1\"}"
2) "10"
3) "{\"Id\":\"3\",\"Score\":15,\"UserName\":\"Test3\"}"
4) "15"
5) "{\"Id\":\"2\",\"Score\":23,\"UserName\":\"Test2\"}"
6) "23"
7) "{\"Id\":\"6\",\"Score\":23,\"UserName\":\"Test5\"}"
8) "23"
9) "{\"Id\":\"5\",\"Score\":100,\"UserName\":\"Test5\"}"
10) "100"
11) "{\"Id\":\"4\",\"Score\":250,\"UserName\":\"Test4\"}"
12) "888"
person Liviu Costea    schedule 09.09.2015