How add array to redis? - php

participants
I use REDIS database and use PHP client http://rediska.geometria-lab.net/documentation/
Here i found type Sorted sets and try create users list for current user.
My code is:
$sortedSet = new Rediska_Key_SortedSet('userslist'); // use collaction userslist
$sortedSet[1] = array('name' => 'Max');
$sortedSet[1] = array('name' => 'Vasile');
As I understand userslist indicates the name of the collection, and the number 1 in $ sortedSet [1] key. Then, in the console through the client redis-cli write:
127.0.0.1:6379> SMEMBERS 1: userslist
(empty list or set)
and get a empty blank ... prompt, what am I doing wrong? May be my concept is wrong?

The sorted set commands is prefixed with Z.
http://redis.io/commands#sorted_set
Try:
ZRANGE userslist 0 -1

SMEMBERS is set not SORTED SETS for sorted sets USE ZSETS
ZADD myzset 3 "two"
ZRANGE myzset 0 -1 WITHSCORES
ZADD expects 3 parameters key, score and member, You are not providing it in your code
ZADD myzset 1 "one"
ZADD myzset 1 "uno"
You will have to use ZRANGE to get the range from sorted sets
ZRANGE myzset 0 -1 // This will give all values in SETS
I do not know how the PHP library works but it seems you have overwriting the members
$sortedSet[1] = array('name' => 'Max');
$sortedSet[1] = array('name' => 'Vasile');
Use Monitor command on redis-cli it will help you to analyze which command redis is processing. So start redis-cli and type monitor and then run your script and check in redis-cli which command it is firing
redis-cli monitor
TIP: Try not to write any code until you understand how things works. E.g. In this case try to understand the difference between SETS and ZSETS

Related

Return BLOB column Which is Empty Or Not Empty as 1 or 0

I have a table with BLOB column that some row has BLOB, some empty.
1 Apple BLOB-8KiB
2 Banana
3 Pear BLOB-6KiB
4 Orange BLOB-7KiB
Is there any way I can use PHP MYSQL to get the array like this:
$fruit = array(
array("1",Apple,1),
array("2",Banana,0),
array("3",Pear,1),
array("4",Orange,1)
);
I just want to change the BLOB data with 1, Empty with 0 in my PHP array. Pls help.
Your select statement can use IF and ISNULL (note these are not widely implemented in the same format on different database backends, this is for MySQL).
So you would use:
SELECT ID, Name, IF(ISNULL(BlobField), 0, 1) FROM TableName
IF allows you to choose one of two values according to a logical operation.
ISNULL returns true or false according to whether or not the value is NULL

php Mongo driver cursor traveling take long so much

I have a query like this
$results = $collection->find([
'status' => "pending",
'short_code' => intval($shortCode),
'create_time' => ['$lte' => time()],
])
->limit(self::BATCH_NUMBER)
->sort(["priority" => -1, "create_time" => 1]);
Where BATCH_SIZE is 70.
and i use the result of query like below :
foreach ($results as $mongoId => $result) {
}
or trying to convert in to array like :
iterator_to_array($results);
mongo fetch data and traveling on iterate timing is :
FetchTime: 0.003173828125 ms
IteratorTime: 4065.1459960938 ms
As you can see, fetching data by mongo is too fast, but iterating (in both case of using iterator_to_array or using foreach) is slow.
It is a queue for sending messages to another server. Destination server accept less than 70 documents per each request. So i forced to fetch 70 document. anyway. I want to fetch 70 documents from 1,300,000 documents and we have problem here.
query try to fetch first 70 documents which have query conditions, send them and finally delete them from collection.
can anybody help? why it takes long? or is there any config for accelerating for php or mongo?
Another thing, when total number of data is like 100,000 (isntead of 1,300,000) the traveling is fast. traveling time will increase by increasing number of total documents.
That was because of sorting.
The problem :
Fetching data from mongo was fast, but traveling in iterator was slow using foreach.
solution :
there was a sort which we used. sorting by priority DESC and create_time ASC. These fileds was index ASC seperatly. Indexing priority DESC and create_time ASC together fixed problem.
db.queue_1.createIndex( { "priority" : -1, "create_time" : 1 } )
order of fileds on indexing is important. means you should use priority at first. then use create_time.
because when you try to sort your query, you sort them like below :
.sort({priority : -1, create_time : 1});

Redis diff between two lists?

As I know sDiff works only with sets.
But how can i get diff between indexed lists?
....
$Redis->lPush("KEY1", "Value1");
$Redis->lPush("KEY1", "Value2");
$Redis->lPush("KEY1", "Value3");
$Redis->lPush("KEY2", "Value1");
$Redis->lPush("KEY2", "Value3");
$Redis->lPush("KEY2", "Value4");
$Redis->sDiff("KEY1", "KEY2");
....
There is no built-in command for that - your options are either pull the two lists and perform the comparison (for diff) in the client, or write a Lua script that is run with the EVAL command to perform it server-side. Here's an example for such a script:
--[[
LDIFF key [key ...]
Returns the elements in the first list key that are also present in all other
keys.
]]--
-- A utility function that converts an array to a table
local function a2t(a)
local t = {}
for i, v in ipairs(a) do
t[v] = true
end
return t
end
-- A utility function that converts a table to an array
local function t2a(t)
local a = {}
for k, _ in pairs(t) do
a[#a+1] = k
end
return a
end
-- main
local key = table.remove(KEYS,1)
local elems = a2t(redis.call('LRANGE', key, 0, -1))
-- iterate remaining keys
while #KEYS > 0 do
key = table.remove(KEYS,1)
local check = a2t(redis.call('LRANGE', key, 0, -1))
-- check each element in the current key for existence in the first key
for k, _ in pairs(elems) do
if check[k] then
elems[k] = nil
end
end
end
-- convert the table to an array and reply
return t2a(elems)
Running this with redis-cli looks like this:
$ redis-cli LPUSH key1 value1 value2 value3
(integer) 3
$ redis-cli LPUSH key2 value1 value3 value4
(integer) 3
$ redis-cli --eval ldiff.lua key1 key2
1) "value2"
Redis doesn't have in-built support for finding list differences. But there is a workaround. By seeing the syntax of your code, I assume you are working on php. PHP array_diff() is to rescue. Following steps should work.
$a1 = $Redis->lPush("KEY1",0,-1)
$a2 = $Redis->lPush("KEY2",0,-1)
diff = array_diff($a1,$a2)
This approach can be translated to any other programming language.
p.s. If the lists are huge, make sure you get the difference in batch, instead of loading all the items at once.

Pluck not working as expected in laravel

Following on from my previous question, I need to get an array of a list of random ids from a model, I do:
User::all('id')->random(2)->pluck('id')->toArray()
The above works as expected, plucking 2 ids and putting them in an array:
array:2 [
0 => 63
1 => 270
]
When I switch it to just one random user though:
User::all('id')->random(1)->pluck('id')->toArray()
The entire table is returned.
array:200 [
0 => 63
1 => 270
2 => 190
...
]
My plan is to use the following to get between 1 and 10 users:
User::all('id')->random(rand(1,10))->pluck('id')->toArray()
But how can I make this work when only 1 random user is selected, why is the entire table being returned?
You can use your database to randomize your users, and take full advantage of the query builder and its take method.
User::inRandomOrder()
->take(rand(1,10))
->pluck('id')
->toArray();
inRandomOrder was added in Laravel 5.2+, so if you have less, you can do orderBy(DB::raw('RAND()')) for MySQL (see this post to learn more Laravel - Eloquent or Fluent random row)
random(1) will not return a collection, while random(2) and above will. You can first get the query and then handle the results differently dependent on whether or not the result was a collection.

Match SteamID with ban duration from listid result

I use a php library to execute commands on a srcds-server via rcon. In this case I want to get all bans and their durations. When I execute listid via rcon, I get, after some parsing, for example this text:
1 STEAM_1:0:12345678 : permanent 2 STEAM_1:0:87654321 : 30.000 min
Now I want to get an array which contains the SteamID and the duration per set, like this:
$Bans = [
"STEAM_1:0:12345678" => "permanent",
"STEAM_1:0:87654321" => "30.000 min",
]
Since I can't use explode in a good way to do this for me (or at least I don't know how I should do that), I want to try it with regex. My attempt so far:
/^(?:\d\s)(STEAM_[0-5]:[01]:[0-9]{1,8})(?:\s:\s)(permanent|\d{1,}\.000\smin)/g
But that doesn't match it in the right way. How would you do it?
The right regex with preg_match_all is:
preg_match_all("/(?:\d\s)(STEAM_[0-5]:[01]:[0-9]{1,8})(?:\s:\s)(permanent|\d{1,}\.000\smin)/", $input_lines, $output_array);
I needed to remove the ^. Now, I don't even have to do all the exploding beforehand. I matches the right parts even from the raw result:
ID filter list: 2 entries 1 STEAM_1:0:12345678 : permanent 2 STEAM_1:0:87654321 : 30.000 min L 05/20/2015 - 15:48:53: rcon from "188.40.142.20:60799": command "listid"

Categories