I'm new to Redis and I have to say I love it till now :)
I'm bumping into an issue I'm not sure how to solve it in the more efficient way.
I have a SET
of HASH
. Each HASH
describe a post.
Here is the code to create and store the 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());
Now, previously I was storing all the post's attributes in a data
field of the HASH
(json_encoded) and I was fetching the information like this:
$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);
}
It was working great, I had all the posts information :)
But I had conflicts when updating the post in Redis (concurrent updates), so I've decided to have all the post's attributes in separated fields
of the HASH
and it fixed my issue of conflicts.
Now the problem I have is to fetch the HASH
from my SET
. Do I have to specify every single fields like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => array('post:*->created', 'post:*->author', 'post:*->message')
));
Or is there another way to fetch the full HASH
directly within the SET
?
I heard about pipeline
but I'm not sure it's what I'm looking for and if I can use it with phpredis
Cheers, Maxime
UPDATE
I'm not sure I explained myself clearly. I have some elements in a set (post_id
).
I want to get the first 10 posts of the SET
, which means I want 10 hash
(with all their fields and value) in order to build a post
object.
I was previously storing all the object information in one field of the hash (data
), now I have one field per attribute of the object.
before:
myHash:<id> data
now:
myHash:<id> id "1234" created "2010-01-01" author "John"
Before I was using SORT
to fetch the top 10 posts (and paginate easily), like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array(0, 10),
'get' => 'post:*->data '
));
Now that I have X members to my hash I'm wondering what is the best solution.
Is it:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => 'post:*->data '
));
Or maybe:
$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);
}
Or finally:
$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();
Or something else that I don't know yet? What is the best, faster way to do this?