is there a way to perform get and set atomically in redis? - redis

I'm using jedis, and wish to get the result of a key and modify it and then store it back,
String dataToModify = jedis.get(parent_id);
//some modify eg:
modifiedData = dataToModify + "modify";
jedis.set(parent_id, modifiedData);
but I then realized that if someone else modified data in key parent_id, between this get and set, there will be collision. the watch-multi-exec does not work since I need to get the value of key parent_id during the transaction. Is there any other way to do this atomically? thanks

Not sure regarding the exact jedis syntax, but Redis' WATCH/MULTI/EXEC will let you do that (I.e. run the get/set flow atomically). Alternatively, if you implement your workflow in a server-side Lua script, that would also guarantee atomicity.

How about saving the date in epoch (also known as unix time) value, this way you can treat your date as a number and use INCRBY command e.g.:
jedis.incrby(parent_id, modify);

Related

Is there a function in sPacy to get the string given hash?

Basically looking for opposite of spacy.strings.get_string_id() which does not need to load the language model to get the vocabulary. I tried StringStore methods, but you need to add the string first or else you get a "Can't retrieve string for hash 'xxx'" error.
Use case is the hash is serialized then it is unserialized somewhere else.
No, you will need to keep a copy of the StringStore from the pipeline you used to process your documents in order to look up strings for hashes in the future.
In the end, it's nothing more than a list of strings that have been seen before, either as tokens or annotations, which you can simply re-add to a new StringStore.

SHOW KEYS in Aerospike?

I'm new to Aerospike and am probably missing something fundamental, but I'm trying to see an enumeration of the Keys in a Set (I'm purposefully avoiding the word "list" because it's a datatype).
For example,
To see all the Namespaces, the docs say to use SHOW NAMESPACES
To see all the Sets, we can use SHOW SETS
If I want to see all the unique Keys in a Set ... what command can I use?
It seems like one can use client.scan() ... but that seems like a super heavy way to get just the key (since it fetches all the bin data as well).
Any recommendations are appreciated! As of right now, I'm thinking of inserting (deleting) into (from) a meta-record.
Thank you #pgupta for pointing me in the right direction.
This actually has two parts:
In order to retrieve original keys from the server, one must -- during put() calls -- set policy to save the key value server-side (otherwise, it seems only a digest/hash is stored?).
Here's an example in Python:
aerospike_client.put(key, {'bin': 'value'}, policy={'key': aerospike.POLICY_KEY_SEND})
Then (modified Aerospike's own documentation), you perform a scan and set the policy to not return the bin data. From this, you can extract the keys:
Example:
keys = []
scan = client.scan('namespace', 'set')
scan_opts = { 'concurrent': True, 'nobins': True, 'priority': aerospike.SCAN_PRIORITY_MEDIUM }
for x in (scan.results(policy=scan_opts)): keys.append(x[0][2])
The need to iterate over the result still seems a little clunky to me; I still think that using a 'master-key' Record to store a list of all the other keys will be more performant, in my case -- in this way, I can simply make one get() call to the Aerospike server to retrieve the list.
You can choose not bring the data back by setting includeBinData in ScanPolicy to false.

Redis Hash/Set Storing multiple types

I am new to redis so I apologize if this question seems naive. I want to create a hash of the following type:
item = {{"bititem":00001010000100...001010},
{"property":1}}
Where bititem is a bit array created by setbit and property is a simple integer value. Is there any way to do this in redis or do I have to create different objects?
From your example, it is not clear to me why you need the extra depth-level around bititem.
Also, it is not clear to me what you want to do with it afterwards. So I give you three scenario's:
1. Serialized:
You can always serialize your data if it involves multiple levels. Most efficient is MsgPack, second best is JSON. You can deserialize the data in Lua-Redis when needed.
2. Hashed:
If you don't need multiple levels, simply do:
HSET item:01 bititem 00001010000100...001010
HSET item:01 property 1
Only do this though, if you really need to extract the different datamembers often. Separate members have quite some overhead. In general, I prefer to serialize the whole object (with a SET or a HSET).
3. Bitwise enabled:
If you want to make use of Redis' bitwise operations, you need to use simple strings (GET/SET). For example:
SET item:01:bititem "00001010000100...001010"
SET item:01:property 1
or even better:
SET item:01:bititem "00001010000100...001010"
SET item:01:properties [all-other-properties-serialized-as-msgpack]
Hope this helps, TW

How to identify Drive ID?

The new Google Drive Android API has 2 types of string IDs available, the 'resource' ID and the 'encoded' ID.
'encoded' id from DriveId.encodeToString()
"DriveId:CAESHDBCMW1RVVcyYUZKZmRhakIzMDBVbXMYjAUgssy8yYFRTTNKRU55"
'resource' id from DriveId.getResourceId()
"UW2aFJfdajB3M3JENy00Ums0B1mQ"
In the process I end-up with a string that can contain any one of them (result of some timing issues). My question is:
If I need to 'parse' the string in order to identify the type, is there a characteristic I can rely on? For instance:
'encoded' id will always start with 'DriveId:' substring
'resource' id will have some length limit
can I abuse error return from 'decodeFromString()'?
or should I form (pre-pend) the string container with my own tag? What could be the minimal 'safe' tag (i.e. what will never appear in the beginning of these ids) ?
Please point me in the right direction so I don't have to re-do it with the next release.
I have run into yet another issue that should be mentioned here so others don't waste time falling into the same pit. The 'resourceID' can be ported and will remain unique for the object it identifies, where 'encodedID' has only 'device' scope. Means that you CAN'T transfer 'encodedID' to another device (with the same account) and try to retrieve file/folder with it. So I assume it is unique to a Google Play Services instance.
Please do not rely on any formatting of either ID type. This are subject to change without notice.
If you need to use both, and track the differences between them you should have your own method of doing so within your app.
Really, you should probably always just store the encoded ID since this one is always guaranteed to present, and if it contains a resourceId, its easy to get back out.

In Redis, command for retrieving values from sorted-set

I tried adding some sample score-value pairs to redis sorted set using below code:
String key = "set";
redis.zadd(key, 5, "1034");
redis.zadd(key, 2, "1030");
redis.zadd(key, 1, "1089");
and tried retrieving it using byteArray and BitSet
byte[] byteArr = redis.get(key.getBytes());
BitSet bitSet = fromByteArrayReverse(byteArr);
System.out.println(bitset.toString()));
also i tried executing
System.out.println(redis.get(key.getBytes()));
which is supposed to give me an address of the byte-array
But for both of these commands i get the error
" ERR Operation against a key holding the wrong kind of value"
So can anyone please tell me why does this error occur in the first place and also the correct redis command/code to retrieve values from a redis sorted-set??
What you want is calling
ZSCORE key "1034"
Or in the case of wanting only elements between two particular scores
ZRANGEBYSCORE key lower upper
Since you also have "rank" (position or index, as in a list) you can also ask for example for the first three elements in your set
ZRANGEBYRANK key 0 2
The error you are getting is because once you assign a value to a key, that value defines the type of the internal structure on redis, and you can only use commands for that particular structure (or generic key commands such as DEL and so on). In your case you are trying to mix sorted sets with byte operations and it doesn't match.
To see all sorted set commands, please refer to http://redis.io/commands#sorted_set