복붙노트

[REDIS] 어떻게 레디 스 'ZRANK에 같은 점수에 대한 동일한 순위를 얻으려면?

REDIS

어떻게 레디 스 'ZRANK에 같은 점수에 대한 동일한 순위를 얻으려면?

다음과 같이 내가 점수 (5 개) 회원이있는 경우

a - 1
b - 2
c - 3
d - 3
e - 5

C 복귀 ZRANK D의 복귀 3의 2 ZRANK 같은 점수에 대한 동일한 순위를 얻을 수있는 방법이 있나요? 예 : ZRANK C = 2, D = 2, E = 3 그렇다면, 그럼 어떻게 스프링 데이터 레디 스에서 그것을 구현하는 방법?

해결법

  1. ==============================

    1.실제 솔루션은 종류의 원래의 질문에서 누락의있는 요구 사항에 맞게해야합니다. 나의 첫번째 대답은 작은 데이터 집합을 가정했지만, 밀도가 적어도 O (N)에서 (예를 들어를 통해 루아) 수행 순위로이 방법은 확장되지 않습니다.

    실제 솔루션은 종류의 원래의 질문에서 누락의있는 요구 사항에 맞게해야합니다. 나의 첫번째 대답은 작은 데이터 집합을 가정했지만, 밀도가 적어도 O (N)에서 (예를 들어를 통해 루아) 수행 순위로이 방법은 확장되지 않습니다.

    그래서, 점수 많은 사용자가 있다고 가정하고, 제안 for_stack 방향은 여러 데이터 구조가 결합되어있는, 더 낫다. 나는 이것이 그의 마지막 말의 요점 믿습니다.

    사용자의 점수를 저장하려면 당신은 해시를 사용할 수 있습니다. 개념적으로는 실제로 모든 사용자 점수의 해시를 저장하는 데 하나의 키를 사용할 수 있지만 당신은 그것을 확장 할 수 있도록 해시 해시 할 것입니다. 이 예를 간단하게 유지하기 위해, 나는 해시 스케일링을 무시하는 것입니다.

    이것은 당신이 루아에서 사용자의 점수를 (갱신)을 추가 거라고하는 방법입니다 :

    local hscores_key = KEYS[1]
    local user = ARGV[1]
    local increment = ARGV[2]
    local new_score = redis.call('HINCRBY', hscores_key, user, increment)
    

    다음으로, 우리는 우리가 또 다른 해시를 유지할 수 있도록 개별 점수 값에 따라 사용자의 현재 카운트를 추적 할 :

    local old_score = new_score - increment
    local hcounts_key = KEYS[2]
    local old_count = redis.call('HINCRBY', hcounts_key, old_score, -1)
    local new_count = redis.call('HINCRBY', hcounts_key, new_score, 1)
    

    이제, 우리가 관리 할 필요가있는 마지막 일이 점수에 따라 순위 정렬 된 세트입니다. 모든 새로운 점수는 ZSET의 구성원으로 추가되며, 더 이상 사용자가 점수가 제거됩니다 :

    local zdranks_key = KEYS[3]
    if new_count == 1 then
      redis.call('ZADD', zdranks_key, new_score, new_score)
    end
    if old_count == 0 then
      redis.call('ZREM', zdranks_key, old_score)
    end
    

    이 3 조각 스크립트의 복잡도는 O (logN)이 정렬 된 설정을 사용하지만, N은 개별 점수 값의 수, 시스템에없는 사용자가 유의 때문. 사용자의 밀도는 다른, 짧고 간단한 스크립트를 통해 이루어집니다 순위하기 :

    local hscores_key = KEYS[1]
    local zdranks_key = KEYS[2]
    local user = ARGV[1]
    
    local score = redis.call('HGET', hscores_key, user)
    return redis.call('ZRANK', zdranks_key, score)
    
  2. ==============================

    2.두 소트 세트와 목표를 달성 할 수 있습니다 점수 매핑 멤버 하나와 순위 매핑 점수에 대한 하나.

    두 소트 세트와 목표를 달성 할 수 있습니다 점수 매핑 멤버 하나와 순위 매핑 점수에 대한 하나.

    더하다

    검색

    원자 적 실행 추가를 포장하고, 2 루아 스크립트로 작업을 검색하기 위해.

  3. ==============================

    3.https://github.com/antirez/redis/pull/2011 - - 죽은이지만, 즉석에서 조밀 한 순위를 만들기 위해 나타납니다 그런 다음이 풀의 요청이있다. 원래 문제 / 기능 요청은 (https://github.com/antirez/redis/issues/943) 그것이 / CC @antirez : 되살리는 가치가있다 그래서 아마 약간의 관심을 가지고

    https://github.com/antirez/redis/pull/2011 - - 죽은이지만, 즉석에서 조밀 한 순위를 만들기 위해 나타납니다 그런 다음이 풀의 요청이있다. 원래 문제 / 기능 요청은 (https://github.com/antirez/redis/issues/943) 그것이 / CC @antirez : 되살리는 가치가있다 그래서 아마 약간의 관심을 가지고

  4. ==============================

    4.순위는 소트 세트에서 고유하고 같은 점수 요소는 어휘 (위) 정렬됩니다.

    순위는 소트 세트에서 고유하고 같은 점수 요소는 어휘 (위) 정렬됩니다.

    이 "순위 밀도"를 수행 더 레디 스 명령이 없다

    당신은, 그러나, 정렬 된 세트의 범위를 가져, 그리고 요청 폼에 감소 루아 스크립트를 사용할 수 있습니다. 이 작은 데이터 세트에서 일할 수있는,하지만 당신은 규모에 대한 더 복잡한 유증 뭔가해야 할 것이다.

  5. from https://stackoverflow.com/questions/52152217/how-to-get-same-rank-for-same-scores-in-redis-zrank by cc-by-sa and MIT license