redis的一些命令和执行的返回值

方法含义示例命令返回值
select选择dbselect 0"OK"
字符串
SET字符串set string 888"OK"
__set string 888"OK"
GET字符串get string"888"
__get string1null
哈希
hset设置hash值hset aa abc 123"1"
__hset aa abcd 123"ERR wrong number of arguments for 'hset' command"
_warning注意, hash里面的value是唯一值, 不可相同, 其他hashkey的值如果和已有的相同则报错
__hset aa abc 1234"0"
_warning注意, hash里面key的value变化返回为0
集合
sadd集合SADD saddkey redis"1"
__SADD saddkey redis"0"
_warning这个里面保存的是唯一值的集合
有序集合
zadd有序集合ZADD zset 111 a1"1"
__ZADD zset 11 a1"ERR wrong number of arguments for 'zadd' command"
_warning注意, 有序集合里面的值不能通过该发放修改
__ZADD zset 111 a2"1"
__ZADD zset 111 a2"0"
ZREM移除有序集合的的setkeyZREM zset a1"1"
__ZREM zset a1"0"

普通写法

function get_chance($chance = [
    '和谐' => 3000,
    '爱国' => 5000,
    '敬业' => 110,
    '友善' => 1000,
    '富强' => 3000,
])
{
    $cardRange = [];
    $num = rand(0, array_sum(array_values($chance)));
    $total = 0;
    foreach ($chance as $key => $value) {
        $totalBefore = $total;
        $total += $value;
        if ($num >= $totalBefore && $num < $total) {
            return $key;
        }
        $cardRange[$key] = [$totalBefore, $total];
    }
    return $key;
}

在swoole环境中的写法, 兼容所有环境

function get_chance($chance = [
    '和谐' => 3000,
    '爱国' => 5000,
    '敬业' => 110,
    '友善' => 1000,
    '富强' => 3000,
])
{
    // 在协程中避免rand一段时间内值一致的问题
    $cardRange = [];
    $total = array_sum(array_values($chance));
    // $randValue = substr(explode(' ', microtime())[0], 0, 8);
    $randValue = strrev(substr(explode(' ', microtime())[0], 2, 6)) / 1000000;
    $rangeBefore = 0;
    $total2 = 0;
    foreach ($chance as $key => $value) {
        $total2 += $value;
        $rangeAfter = $total2 / $total;
        if ($randValue >= $rangeBefore && $randValue < $rangeAfter) {
            return $key;
        }
        $rangeBefore = $rangeAfter;
    }
    return $key;
}

校验数据和预期值的差异量

$t = [
    '记' => 300,
    '得' => 900,
    '我' => 150,
];
$r = [
    '记' => 0,
    '得' => 0,
    '我' => 0,
];
for ($k = 0; $k <= 10000; $k++) {
    $r[get_chance($t)]++;
}
var_dump($r);

方法说明方法返回值
json_search按给定字符串关键字搜索json,返回匹配的路径json_search('["10","2","1"]','all','1')"$[2]"
--查询路径2json_search('{"a":"123","b":{"c":"d","e":"f"}}','all','f')"$.b.e"
json_merge合并json数组或对象json_merge('["10","2"]','["10","9"]')["10", "2", "10", "9"]
JSON_MERGE_PRESERVE合并json数组或对象,代替json_merge用途JSON_MERGE_PRESERVE ('["10","2"]','["10","9"]')["10", "2", "10", "9"]
json_remove删除json数据json_remove('{"a":"123","b":"123"}','$.a'){"b": "123"}
--删除数组中值json_remove('["10","2","1","6"]','$[2]')["10", "2", "6"]
--删除当数组中存在某一个值时执行删除(注意, 当没有该值时, 这个查询的返回值为null)json_remove('["10","2","1","6"]',json_unquote(json_search('["10","2","1","6"]','all','1')))["10", "2", "6"]
--删除当数组中存在某一个值时执行删除(安全的操作, 只要数据量不大于99999就没问题)json_remove('["10","2","1","6"]',IFNULL(json_unquote(json_search('["10","2","1","6"]','all','11')),'$[9999999]'))["10", "2", "1", "6"]
json_keys提取json中的键值为json数组json_keys('{"a":"123","b":{"c":"d","e":"f"}}')["a", "b"]
json_length返回json的长度json_length('["10","2","10","9"]')4
--如果为复杂的对象结构, 这个长度依旧为根部key的个数json_length('{"a":"123","b":{"c":"d","e":"f"}}')2
json_unquote去除json字符串的引号,将值转成string类型
json_extract提取json值json_extract(openid,REPLACE(json_unquote(json_search(openid,'all','2')),'app_id','openid'))"oKTQ41OqjJ848_SPe7wbTZO9RmOE"openid 字段的数据包 '[{"app_id": "1", "openid": "oromp5ZEhkLz1BXELF-cxyqap-uw"}, {"app_id": "2", "openid": "oKTQ41OqjJ848_SPe7wbTZO9RmOE"}]'
json_replace替换值(只替换已经存在的旧值)实际测试如果值不存在, 并不会导致原有数据丢失
json_set只要目标值不为null,不为数组即可设置 json_set(data,"$.address","Guangzhou")

正常的key查询哪些文档大家都能用, 但是如果key是 abc:de-fg 这样的值呢, 那么文档中那些办法无法实现查询了

尝试了好久, 终于找到了对应的解决办法

非法键值查询办法

比如demo为
json_data
{"abc:de-fg": "aa"}
那么取出这个值的办法为 json_data->'$."abc:de-fg"'
注意, 只能里面使用双引号的写法

JSON内的键值是否为null的判断方法

json_data
{"abc:de-fg": "aa","b":null}

// 判断里面的值等于null的判断方式
json_data->'$.b'=CAST('null' AS json)

业务场景
有一张表 project_users

表的数据列表
openid
------
[{"app_id": "1", "openid": "oromp5ZEhkLz1BXELF-cxyqap-uw"}, {"app_id": "2", "openid": "oKTQ41OqjJ848_SPe7wbTZO9RmOE"}]
[{"app_id": "1", "openid": "oromp5QBh9-a8VQlM99knmq2eM7k"}]
(NULL)
把表扁平化下来
SELECT 
uid
,openid
,openid->'$[*].app_id'
,json_search(openid->'$[*].app_id','all','2')
,openid->'$[0].openid'
,a.app_id
,a.json_openid
 FROM `project_users`,JSON_TABLE(openid, '$[*]' COLUMNS(app_id INT path '$.app_id',json_openid VARCHAR(50) path '$.openid')) a

-----

      uid  openid                                                                                                                  openid->'$[*].app_id'  json_search(openid->'$[*].app_id','all','2')  openid->'$[0].openid'           app_id  json_openid                   
---------  ----------------------------------------------------------------------------------------------------------------------  ---------------------  --------------------------------------------  ------------------------------  ------  ------------------------------
100001002  [{"app_id": "1", "openid": "oromp5ZEhkLz1BXELF-cxyqap-uw"}, {"app_id": "2", "openid": "oKTQ41OqjJ848_SPe7wbTZO9RmOE"}]  ["1", "2"]             "$[1]"                                        "oromp5ZEhkLz1BXELF-cxyqap-uw"       1  oromp5ZEhkLz1BXELF-cxyqap-uw  
100001002  [{"app_id": "1", "openid": "oromp5ZEhkLz1BXELF-cxyqap-uw"}, {"app_id": "2", "openid": "oKTQ41OqjJ848_SPe7wbTZO9RmOE"}]  ["1", "2"]             "$[1]"                                        "oromp5ZEhkLz1BXELF-cxyqap-uw"       2  oKTQ41OqjJ848_SPe7wbTZO9RmOE  
100001006  [{"app_id": "1", "openid": "oromp5QBh9-a8VQlM99knmq2eM7k"}]                                                             ["1"]                  (NULL)                                        "oromp5QBh9-a8VQlM99knmq2eM7k"       1  oromp5QBh9-a8VQlM99knmq2eM7k  

查询指定key

demo 数据包
data_cache
----------
{"courses:220-0": 24, "course_classes:1": 25701,"test":"666"}

如果我们查询test值或者移除非常简单
SELECT data_cache->'$.test',json_remove(data_cache,'$.test') FROM `daily_caches` WHERE id=32

result
data_cache->'$.test'  json_remove(data_cache,'$.test')                  
--------------------  --------------------------------------------------
"666"                 {"courses:220-0": 24, "course_classes:1": 25701}  


但是如果我们查询里面的 course_classes:1 key, 上面的方法就不行了, 需要下面的写法才行, 试了好久才试出来的

SELECT data_cache->'$."course_classes:1"',json_remove(data_cache,'$."course_classes:1"') FROM `daily_caches` WHERE id=32

result
data_cache->'$."course_classes:1"'  json_remove(data_cache,'$."course_classes:1"')  
----------------------------------  ------------------------------------------------
25701                               {"test": "666", "courses:220-0": 24}