【问题标题】:How to SORT a SET and GET the full HASH如何对 SET 进行排序并获取完整的 HASH
【发布时间】:2014-02-26 07:02:23
【问题描述】:

我是 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());

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

$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 中更新帖子时遇到了冲突(并发更新),所以我决定将所有帖子的属性放在 HASH 的分隔 fields 中,它解决了我的冲突问题。

现在我的问题是从我的SET 获取HASH。我是否必须像这样指定每个字段:

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

或者还有其他方法可以直接在SET 中获取完整的HASH

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

干杯,马克西姆


更新

我不确定我是否清楚地解释了自己。我有一组元素 (post_id)。 我想获取SET 的前 10 个帖子,这意味着我需要 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();

或者其他我还不知道的东西? 最好、更快的方法是什么?

【问题讨论】:

  • 每个散列键的“X 成员”是不变的吗?只是“id”、“created”、“author”?
  • 是的,但我有超过 3 个字段,我有 10 个
  • 好吧,你可以在sort命令中写10个'get pattern',没有限制。这是最快的方法。
  • 你有没有发现哪种方法最有效?

标签: redis phpredis


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我想从 Set 而不是散列中做到这一点。我知道hashgetall,但这不是我要找的
    猜你喜欢
    • 2021-04-06
    • 1970-01-01
    • 2016-11-07
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多