Подтвердить что ты не робот

Redis: Как пересечь "нормальный" набор с отсортированным набором?

Предположим, что у меня есть набор (или отсортированный набор или список, если это было бы лучше) A от 100 до 1000 строк.

Затем у меня есть отсортированный набор B многих других строк, скажем, один миллион.

Теперь C должно быть пересечением A и B (строк, конечно).

Я хочу иметь каждый кортеж (X, SCORE_OF_X_IN_B), где X находится в C.

Любая идея?

У меня есть две идеи:

  • Interstore
    • store A a отсортированный набор, каждый балл которого равен 0
    • interstore to D
    • получить каждый элемент D
    • удалить D
  • Простой цикл в клиенте
    • loop over A в моей клиентской программе
    • получить zscore для каждой строки

В то время как 1. имеет слишком много накладных расходов на стороне redis (например, должен писать. Страница redis содержит довольно сложную временную сложность, также http://redis.io/commands/zinterstore), 2. было бы | A | подключения к базе данных и не будет хорошим выбором.

Возможно, я мог бы написать redis/lua script, который будет работать как zscore, но с произвольным количеством строк, но я не уверен, разрешает ли мой хост сценарии...

Поэтому я просто хотел спросить SO, если есть элегантное и быстрое решение без скриптов!

4b9b3361

Ответ 1

Существует простое решение вашей проблемы: ZINTERSTORE будет работать с SET и ZSET. Попробуйте:

redis> sadd foo a
(integer) 1
redis> zadd bar 1 a
(integer) 1
redis> zadd bar 2 b
(integer) 1
redis> zinterstore baz 2 foo bar AGGREGATE MAX
(integer) 1
redis> zrange baz 0 -1 withscores
1) "a"
2) "1"

Изменить: Я добавил AGGREGATE MAX выше, так как redis предоставит каждому члену (не отсортированный) набор foo значение по умолчанию 1 и SUM, что с любой счет, который он имеет в (отсортированном) наборе bar.