Map deletion


#1

I have a use-case where i need to store sorted map in aerospike. Also if there is any change in map, i need to replace the whole map . I am not able get the operationType for same. I tried below operation. MapOperation.putItems(new MapPolicy(MapOrder.KEY_ORDERED,MapWriteMode.UPDATE),“testBin”, map)

This operation is not deleting old map entries. This will only replace data for which keys are present and append other key,values. I also wants it to be atomic.


#2

See this sample code. Delete all keys (see call to removeByKeyRange, start = null, end=null) in the operate command before inserting the new map. It will be atomic.

package com.aerospike;

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

import com.aerospike.client.AerospikeClient;
import com.aerospike.client.Record;
import com.aerospike.client.Bin;
import com.aerospike.client.Key;
import com.aerospike.client.Value;
import com.aerospike.client.cdt.MapOperation;
import com.aerospike.client.cdt.MapPolicy;
import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.cdt.MapWriteMode;
import com.aerospike.client.cdt.MapReturnType;
import com.aerospike.client.policy.RecordExistsAction;
import com.aerospike.client.policy.WritePolicy;

public class MapBasedCounter {
        public static void putItemsKOrdered(AerospikeClient client, Key key, Map<Value,Value> m) {
                MapPolicy mPolicy = new MapPolicy(MapOrder.KEY_ORDERED, MapWriteMode.UPDATE);
                Map<Value, Value> m1empty = new HashMap<Value, Value>();
                client.operate(null, key,
                          MapOperation.removeByKeyRange("myMap", null, null, MapReturnType.COUNT),
                          MapOperation.putItems(mPolicy, "myMap", m)
                        );
        }

        public static void main(String[] args) {
                AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);


                Key key1 = new Key("test", "s1", 1);
                WritePolicy policy = new WritePolicy();
                policy.recordExistsAction = RecordExistsAction.UPDATE;

                client.delete(policy, key1);


                Map<Value, Value> m1 = new HashMap<Value, Value>();

                m1.put(Value.get("cv1"), Value.get(11));
                m1.put(Value.get("cv2"), Value.get(12));
                m1.put(Value.get("cv3"), Value.get(13));
                m1.put(Value.get("cv4"), Value.get(14));
                m1.put(Value.get("cv5"), Value.get(15));
                putItemsKOrdered(client, key1,m1);

               System.out.println("\nRecords inserted:");
                System.out.println("\nKey1,KEY_ORDERED:"+ client.operate(null, key1,
                  MapOperation.getByIndexRange("myMap", 0, MapReturnType.VALUE)));

                Map<Value, Value> m1a = new HashMap<Value, Value>();

                m1a.put(Value.get("v1"), Value.get(11));
                m1a.put(Value.get("v2"), Value.get(12));
                m1a.put(Value.get("v3"), Value.get(13));
                m1a.put(Value.get("v4"), Value.get(14));
                putItemsKOrdered(client, key1,m1a);

               System.out.println("\nRecords inserted:");
                System.out.println("\nKey1,KEY_ORDERED:"+ client.operate(null, key1,
                  MapOperation.getByIndexRange("myMap", 0, MapReturnType.VALUE)));

               client.close();
        }
}

Output:

Records inserted:

Key1,KEY_ORDERED:(gen:1),(exp:289330207),(bins:(myMap:[11, 12, 13, 14, 15]))

Records inserted:

Key1,KEY_ORDERED:(gen:2),(exp:289330207),(bins:(myMap:[11, 12, 13, 14]))

#3

There is also a ‘clear’ op, which should achieve the same.

If you want to replace the entire record (the map bin and any other bin that may be on the record), it would be more efficient to use the replace WritePolicy instead of reading the existing record to clear the map.


#4

Oh yes, MapOperation.clear(“myMap”) is a better choice instead of MapOperation.removeByKeyRange(“myMap”, null, null, MapReturnType.COUNT).


#5

Thanks for suggestion. MapOperation.clear() method takes binName, hence i don’t think it reads existing data.


#6

All updates must read the existing data in order to merge bins being written with those already on storage.

If you app doesn’t need the bin merge functionally for these records, then the replace flag should really be used. The read during the write accounts for a significant portion of the time to complete the transaction.


#7

I tried using replace flag in writePolicy.recordExistsAction, it throws exception whenever record is not present. So first i need to check if record exist or not, if record exist then i need to again send write command with replace option.


#8

The replace_only flag throws an exception of the record doesn’t already exist, the replace flag does not.


#9

Can you give a simple example with key-values to explain what you are trying to do. Suppose you have an existing record with myMap bin containing: {k1:v1, k2:v2, k3:v3} … now what are you trying to accomplish?