1

我是 Redis 的新手,我不得不说我喜欢它直到现在 :)

我遇到了一个问题,我不确定如何以更有效的方式解决它。我有一个SETHASH每个HASH描述一个帖子。

这是创建和存储的代码HASH

// Create the HASH
$key = 'post:'.$post->getId();
$this->redis->hSet($key, 'created', $post->getCreated());
$this->redis->hSet($key, 'author', $post->getAuthor());
$this->redis->hSet($key, 'message', $post->getMessage());

// Store the HASH in the SET
$this->redis->sAdd('posts', $post->getId());

现在,以前我将所有帖子的属性存储在(json_encoded) 的一个data字段中HASH,我正在获取如下信息:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => 'post:*->data '
));

if (!is_array($data)) {
    return array();
}

foreach ($data as &$post) {
    $post = json_decode($post, true);
}

它工作得很好,我有所有的帖子信息:)

但是我在 Redis 中更新帖子时遇到了冲突(并发更新),所以我决定将所有帖子的属性分开fieldsHASH它解决了我的冲突问题。

现在我遇到的问题是HASH从我的SET. 我是否必须像这样指定每个字段:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => array('post:*->created', 'post:*->author', 'post:*->message')
));

还是有另一种方法可以HASH直接在SET?

我听说过,pipeline但我不确定它是否是我正在寻找的东西,以及我是否可以使用它phpredis

干杯,马克西姆


更新

我不确定我是否清楚地解释了自己。我在一组 ( post_id) 中有一些元素。我想获得 的前 10 个帖子SET,这意味着我想要 10 个hash(及其所有字段和值)来构建一个post对象。

我以前将所有对象信息存储在哈希 ( data) 的一个字段中,现在我每个对象的属性都有一个字段。

前:

myHash:<id> data

现在:

myHash:<id> id "1234" created "2010-01-01" author "John"

在我SORT用来获取前 10 个帖子(并且很容易分页)之前,如下所示:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array(0, 10),
    'get' => 'post:*->data '
));

现在我的哈希中有 X 个成员,我想知道最好的解决方案是什么。

是吗:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => 'post:*->data '
));

或者可能:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => '#'
));

foreach($data as $post_id) {
   $posts[] = $this->redis->hGetAll('post:'.$post_id);
}

或者最后:

$key = 'posts';
$data = $this->redis->sort($key, array(
    'by' => 'nosort',
    'limit' => array($offset, $limit),
    'get' => '#'
));

$pipeline = $this->redis->multi();
foreach ($data as $post_id) {
    $pipeline->hGetAll('post:'.$post_id);
}

return $pipeline->exec();

或者还有什么我还不知道的?最好、更快的方法是什么?

4

2 回答 2

0

如果你读过 redis 的源码,你会发现这是不可能的。有一种解决方法是使用 lua 脚本在单个 redis 调用中组合 'sort' 和 'hgetall' 命令。

“get pattern”由函数“lookupKeyByPattern”处理。 https://github.com/antirez/redis/blob/unstable/src/sort.c#L61

于 2014-02-26T14:39:27.257 回答
-1

如果您从关于哈希的 redis.io 文档开始,您会发现有一些命令允许您获取多个哈希成员。特别是“ HGETALL ”用于拉取所有字段和值,或“ HMGET ”用于拉取一组字段及其值。

此外,为了设置它们,我建议使用“ HMSET ”一次性设置它们

于 2014-02-26T09:44:04.077 回答