Hello community experts!
I’ve stumbled upon the following use case which involves nested Map operations: My record contains a bin of Map data type. I need to find a value (a nested Map) inside the top-level map and in case the nested Map found I need to update a field in it (created value) and return the whole nested map value to a client. If I call a “put” operation on a nested map for a not-existing record the operation fails. The same “put” operation called on a top-level map for a not-existing record succeeds.
Here’s my bin structure:
bin = { key1 = { created=1, value=value1 }, key2 = { created=2, value=value2 } }
I need to read a nested map for key = key1 and update its key = “created”. Here’s my code:
public class NestedMapUpdate {
public static void main(String[] args) {
try {
AerospikeClient client = new AerospikeClient("localhost", 3000);
Key recordKey = new Key("test", "test", "record1");
Value key1 = Value.get("key1");
MapPolicy policy = new MapPolicy(MapOrder.UNORDERED, MapWriteFlags.UPDATE_ONLY | MapWriteFlags.NO_FAIL);
Operation[] readOps = {
MapOperation.put(policy, "map", Value.get("created"), Value.get(123L), CTX.mapKey(key1)),
MapOperation.getByKey("map", key1, MapReturnType.VALUE)
};
client.operate(client.writePolicyDefault, recordKey, readOps);
} catch (AerospikeException e) {
e.printStackTrace(System.err);
}
}
}
the following exception is thrown:
com.aerospike.client.AerospikeException: Error 4,1,30000,0,0,BB9B135BB0E1B90 88.99.69.12 3000: Parameter error
at com.aerospike.client.command.ReadCommand.parseResult(ReadCommand.java:173)
at com.aerospike.client.command.SyncCommand.execute(SyncCommand.java:97)
at com.aerospike.client.command.SyncCommand.execute(SyncCommand.java:50)
at com.aerospike.client.AerospikeClient.operate(AerospikeClient.java:1288)
at ru.cleverdata.dmpkit.idgraph.aerospike.AerospikeIssue.main(AerospikeIssue.java:32)
As you can see I passed MapWriteFlags to put operation which contains NO_FAIL bits set. So I expected the nested operation will do nothing in case the top-level map or the whole record isn’t found.
How do I solve my case?
aerospike-server: 4.6.0.4 aerospike-client: 4.4.7
Another related question is when I do the same put operation on the top-level map for a non existing record the record gets created with a bin which value is null. MapPolicy defined as
MapWriteFlags.UPDATE_ONLY | MapWriteFlags.NO_FAIL
I expect that no record is created based on the specified MapWriteFlags value.
The code snippet which reproduces this behaviour:
public class NestedMapUpdate {
public static void main(String[] args) {
try {
AerospikeClient client = new AerospikeClient("dmpkit-dev-mn2", 3000);
Key recordKey = new Key("test", "test", "record4");
Value mapKey = Value.get("key1");
MapPolicy policy = new MapPolicy(MapOrder.UNORDERED,
MapWriteFlags.UPDATE_ONLY | MapWriteFlags.NO_FAIL);
Operation[] ops = {
MapOperation.put(policy, "map", mapKey, Value.get(123L)),
};
client.operate(client.writePolicyDefault, recordKey, ops);
// the following record is created despite of MapPolicy
Record record = client.get(client.readPolicyDefault, recordKey);
} catch (AerospikeException e) {
e.printStackTrace(System.err);
}
}
}
Thank you very much in advance!