redis: Possible to update hash values with RedisJSON? - redis

The documentation and Internet at large don't seem to provide any examples of setting values into a JSON object stored as a hash value, yet I know that the Redis collection types are often just hacks that allow their underlying storage to be managed similarly to scalar keys.
Can someone confirm whether RedisJSON supports this or doesn't, and, if it does, provide an example?
Thank you.
https://redis.io/commands/json.set

RedisJSON introduces a new JSON data type to Redis.
Therefor JSON.SET can only act on JSON types.

Related

cloudflare Durable Objects update object value

Halo! I'm recently diving into cloudflare Workers, especially Durable Objects. I could make a simple request which put a js object into the assigned key. Let's say the key is key0, and the put object value is {"fieldA": "val0", "fieldB": "val1"}. In this case, how can i update the field-value of fieldA without removing fieldB? I've tried simply executing put("key0", {"fieldA": "newVal0"}) and it has kept removing {"fieldB": "val1"}.
Of course it is a common behaviour in js operations, but i cannot find out anything like ~["key0"]["fieldA"] = "newVal0" in docs(maybe i'm missing sth). OTL
Hope this question reach to the gurus in the community! Thanks in advance [:
EDIT after the answers:
In theory, it would be wonderful if flare durable objects support and work just like a normal js object. Such possible worker feature feels like a killer app for the cloud db services, since the average cpu time is quite fast and flare also has super low pricing compared to other big bros. If it happens, i would eager to migrate everything into the flare platform [:
Durable Objects' KV storage only supports get and put operations -- it doesn't have any sort of "update". So, you have two options:
get() the key, modify it, and then write the modified version back. This may sound inefficient, but keep in mind that commonly-accessed keys will likely be in in-memory cache. In fact, this get/modify/put implemented in your JavaScript is probably about as fast as any modification operation that Durable Objects itself could possibly implement built-in. That said, you probably don't want to use this approach with large objects, since the whole object has to be written to disk again after every update.
Split your object across multiple keys. E.g. instead of having the key foo map to {"fieldA": "val0", "fieldB": "val1"}, you could have separate keys foo:fieldA and foo:fieldB. Note that you can fetch all the keys at once using storage.list({prefix: "foo:"}). This approach is not as convenient but allows each field to be written separately to disk.
get and put deal with whole JS objects, so if you want to change part of the object you should get it, update it using normal JS, and then put the entire object back.

Redis `keys` and reactive programming

I know keys command should be avoided in Redis because it's an expensive opperation.
But what if I'm using reactive driver (Lettuce) in reactive programming (Spring Data Redis Reactive), where the keys returns a Flux? Would this still be a "problem"?
Obs.: this is not a real situation for me. I'm just trying to understand the correct behaviour, since I've just started with reactive stuff.
Thanks in advance.
As described in the javadoc, scan is still preferable to keys even in reactive environment:
IMPORTANT: It is recommended to use ReactiveRedisOperations.scan() to
iterate over the keyspace as ReactiveRedisOperations.keys(Object) is a
non-interruptible and expensive Redis operation.
The problem with keys is not really on client side, it's rather on Redis side. That's why a reactive client doesn't really make a difference in this case. Although, scan is also better for reactive client because it can request new keys on demand respecting backpressure.
But you have a valid point, it's a bit confusing that keys returns Flux. Based on the semantic of the Redis command I'd rather expect a Mono<List> as return type.

Where is the query tutorial in Redis official site?

I am new to redis and just start to learn it today. The official website does a good job about what the data types are and how to set them. That part is not hard to understand. But the problem is without queries, data becomes meaningless. I really failed to find any good documentation on how to do queries/searches in the official site.
When googling, I found this question Redis strings vs Redis hashes to represent JSON and people are all ignoring queries. I just don't get it at all. Many people suggest to store JSON as a string value to the key. This looks very crazy to me. How can they query JSON keys later? For example, for a user object to store in either key-value data type or hashes, how to query users whose age is greater than 30? That should be a very basic and simplest query for a database.
Thank you very much for your help. I am very confused.
EDITED:
After long time googling, I figured out a basic concept: redis can only query keys, and value are not searchable. Thus to search values, I have to create keys which contain the value. This answers my second question.
But the first and my primary question is where to find query tutorial in redis official site. Since redis is very different from sql db, the question might be changed to where to find data modeling and query tutorial in redis official site. It seems to do queries, I have to create some kind of special keys first. That makes query tutorial become modeling tutorial in the end.
Btw, for those who are new to redis and confused like me, you can read this article Storing and Querying Objects. Even if it has a little bug in it, it clarifies many thing about how to use redis for query. These kind of information really should go into redis official doc.
I really failed to find any good documentation on how to do queries/searches in the official site.
Check the command manual for how to query different data structures.
How can they query JSON keys later
JSON is NOT a built-in data structure for Redis. If you want to query JSON data you need to build the index with Redis' built-in data structures by yourself, or you might want to try RedisJSON, which is a Redis module for processing JSON data.

Best way to serialize a byte array key to Redis with Booksleeve

I need to find the best implementation to send a byte array to the key space of a Redis Server with Booksleeve.
I tried different implementation like UTF8 Encoding but i don't know what is the most optimized one in memory of redis server (i will worked with millions of key like this so i really need the shortest in memory key).
Is anyone has already had this requirement?
In the current build for simplicity I've stuck to string keys, however the code would handle binary fine - it uses the binary API. IIRC I received a patch in my inbox just this week that adds binary key support.
Since it seems to be in demand I'll look at that this week.
Edit: a week came and went; the reason being that I'm also doing some work on redis-cluster support, which is going to need some new interfaces anyway, because:
not all operations are supported
parallel (numbered) databases aren't supported
So basically my plan is to roll both pieces of work into the same branch, giving:
a new set of interfaces
which use a struct for the key parameter with an implicit conversion operator from string and byte, allowing either to be used interchangeably
with the redis-cluster and redis-server commands on separate APIs
and a new method on the old connection to get one of the new APIs on a per-DB basis, i.e. Database(3).Keys.Remove(key); or something like that
ETA is still imaginary, but I wanted to explain why I hadn't simply thrown in the existing patch - I think the advent of redis-cluster makes it a good time to revisit the entire API, (but obviously in a way that doesn't break existing code).

Best way to store a small key-value list in Redis

I'm trying to use Redis as a primary database for a small game I'm making (mostly to mess around with programming and using Redis).
However I came across a scenario that I couldn't find an answer to:
I wish to store a list of the names of different maps that people can be on (not many of them) along with their id. Note: I never need to get the ID from the name.
The two ways I believe this can be done are either storing the information as a string or as a hash.
i.e:
1) String based:
set maps:0 "Main"
set maps:1 "Island"
etc (and maybe a maps:id to
store an auto increment value)
2) Hash based:
hset maps "0" "Main"
hset maps "1" "Island"
etc
My question is which way seems the best. Given that there will never be that many maps I'm leaning towards the single hashed object. Partially because this provides a nice method to return all the maps in existence. But is there any particular reason that the string based queries would be more useful.
Hopefully you can give me some clear information.
Thank you,
Pluckerpluck
The String based values are actually discouraged because it consumes a lot more memory than a hash.
Redis optimizes small hashes and encodes them in a memory efficient manner. This encoding is called zipmap (or ziplist in redis 2.6). See http://redis.io/topics/memory-optimization, specially the section "Use hashes when possible".