2015-09-20 2 views
1

В Redis, что у меня есть упорядоченный набор идентификаторов (которые, забитый отметкой времени):Как вы присоединяетесь к упорядоченному набору с хэшами в Redis?

(name of ordered set) someobject:media 

Member | Score 
1  1442784376400 
2  1442784376420 
3  1442784376450 

Каждый член является идентификатор хэша (как это):

media:1  { 'name': 'something', 'timestamp': '1442784376400 } 
media:2  { 'name': 'somethingelse', 'timestamp': '1442784376420' } 
// and so forth 

ли есть атомная операция, которая позволила бы мне получить все хеши для членов someobject:media?

Я использую Node Redis, который теоретически предоставляет все операции, которые предоставляет redis-cli (как и следовало ожидать).

До сих пор моя единственная мысль перебрать все, как это:

client.zrevrange(['someobject:media', 0, -1], (err, res) => { 
    let promises = res.map(mediaId => { 
    return new Promise((resolve, reject) => { 
     client.hgetall('media:' + mediaId, (err, res) => { 
     resolve(res); 
     }); 
    }); 
    }); 

    Promise.all(promises).then(result => { 
    // do something with the "media" hashes 
    }); 
}); 

Моя кишка говорит мне, что есть какая-то атомном «присоединиться к» операции типа, Redis предоставляет, но может быть, я неправильно. Вышеуказанный метод выглядит совершенно неэффективным.

Другими словами, я хочу присоединиться ко всем media:<id> от заказанного набора someobject:media. Это возможно?

ответ

2

Я не думаю, что sort работает с хэшей. Вы можете использовать режим multi, и он по-прежнему будет эффективным. Multi более типичен в redis, чем что-то вроде объединения. Что-то вроде этого:

client.zrange("members", 0, 100, function (err, replies) { 
    var m = client.multi() 
    replies.forEach(function(item) { 
     m.hgetall(item); 
    }); 
    m.exec(function(err, hashes) { 

    }); 
}); 
+0

Спасибо, это выглядит поближе. Интересно, есть ли способ использовать SCAN в этом типе операции? Например, если я хочу получить все хэши «media: *». –

+0

Я думаю, вы могли бы использовать zscan, если бы вы хотели обработать множество членов в итеративном курсовом стиле, получая небольшое количество данных каждый раз, а не получая большой объем данных в каждом вызове. –

+0

На самом деле, 'MULTI' на самом деле не то, что вам нужно здесь, а скорее конвейерная обработка, но я считаю, что конечный результат будет таким же в этом случае. –

1

My Redis suuuuper ржавый, но я думаю, вы хотите использовать команду (смущающе названную) SORT для этого. Что-то вроде:

SORT someobject:media BY nosort GET media:* 

Я не использовал node_redis, но я думаю, что это означает что-то вроде этого:

client.sort([ "someobject:media", "by", "nosort", "get", "media:*" ], (err, res) => 
    // ... 
}); 
+0

Спасибо большое. Это выглядит потрясающе для списков. Вы знаете, если это возможно для сортированных наборов? Я не вижу отсортированную команду 'SORT'. –

+0

В документах говорится: «Возвращает или сохраняет элементы, содержащиеся в списке, задает или сортирует набор в' key'. » Насколько я знаю, вам нечего делать, чтобы использовать его с отсортированным набором. –

+0

Отлично, спасибо. –

0

Вы можете использовать одну команду сортировки, но вы должны явно указать все имена полей хеш. Для примера, это будет:

sort someobject:media get media:*->name get media:*->time 
1) "something" 
2) "1442784376400" 
3) "somethingelse" 
4) "1442784376420" 
5) (nil) 
6) (nil) 

Для облегчения чтения ответа, вы можете добавить get # получить индекс, а также:

sort someobject:media get # get media:*->name get media:*->time 
1) "1" 
2) "something" 
3) "1442784376400" 
4) "2" 
5) "somethingelse" 
6) "1442784376420" 
7) "3" 
8) (nil) 
9) (nil) 
Смежные вопросы