As_operations_map remove_by_value_range for nested maps

Hello i have map record like this

KEY_ORDERED_MAP('{"campaign.111":{"ttl":777, "value":"1111"}, "campaign.222":{"ttl":666, "value":"2222"}, "campaign.333":{"ttl":555, "value":"3333"}, "campaign.444":{"ttl":1555, "value":"h"}}')

and i want to delete all map items with ttl < NUM

i am doing something like this:

as_cdt_ctx_add_map_key(&ctx, (as_val*)&as_cmp_wildcard);
as_cdt_ctx_add_map_key(&ctx, (as_val*)&key_ttl);
as_operations_map_remove_by_value_range(&ops, bin_str.c_str(), &ctx, (as_val*)&asv_begin, (as_val*)&asv_end, AS_MAP_RETURN_NONE);

but having error like operation is not applicable. Any ideas why, any examples?

Thanks

1 Like

cmp_wildcard is only for matching the rest of a list, such as [‘a’, CMP_WILDCARD] == [‘a’, ‘b’, ‘c’]. It is an error because ctx does not accept CMP_WILDCARD usage. The only way to do what you want (currently) is through UDFs.

If you are willing to change your data model slightly, then you can achieve what you want. Please see this earlier post also for a different problem solved with similar strategy:

You can use the same technique to store your data in a sorted list. Then you can delete by value range. See code example in Java client below:

My test record:

Key myKey = new Key("test", "testset", "CampaignId");
String binName = "myListBin1";
ListPolicy lPolicy = new ListPolicy(ListOrder.ORDERED, ListWriteFlags.DEFAULT);

Note: ListPolicy is ORDERED

Initial Model was a Map of Key:Value pairs

Map: {c1:{"ttl":700, "value":"abc"}, c2:{"ttl":1800, ...} , c3:{"ttl":200, .. }, ...}

Since we cannot do WILDCARD search on Map values elements, we can use a Sorted List of Lists.

Modify data model as: [ [ttl1, c1:{ ...}], [ttl2, c2:{ ... }], [ttl3, c3:{....} ] ]

In this model, let us insert some data in this record:

//Add record data
List<Value> list_cx = new ArrayList<Value>();
list_cx.add(Value.get(1800));
HashMap <String, Value> map_cx = new HashMap <String, Value>();
map_cx.put("ttl", Value.get(1800));
map_cx.put("value", Value.get("bcd1800"));
list_cx.add(Value.get(map_cx));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(list_cx)));
list_cx.clear();

list_cx.add(Value.get(700));
HashMap <String, Value> map_cx = new HashMap <String, Value>();
map_cx.put("ttl", Value.get(700));
map_cx.put("value", Value.get("abc700"));
list_cx.add(Value.get(map_cx));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(list_cx)));
list_cx.clear();

list_cx.add(Value.get(200));
HashMap <String, Value> map_cx = new HashMap <String, Value>();
map_cx.put("ttl", Value.get(200));
map_cx.put("value", Value.get("cde200"));
list_cx.add(Value.get(map_cx));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(list_cx)));
list_cx.clear();

list_cx.add(Value.get(1200));
HashMap <String, Value> map_cx = new HashMap <String, Value>();
map_cx.put("ttl", Value.get(1200));
map_cx.put("value", Value.get("efg1200"));
list_cx.add(Value.get(map_cx));
client.operate(null, myKey, ListOperation.append(lPolicy, binName, Value.get(list_cx)));
list_cx.clear();


System.out.println("My List after data insert: "+ client.get(null, myKey));

Output:

My List after data insert: (gen:4),(exp:0),(bins:(myListBin1:[[200, {ttl=200, value=cde200}], [700, {ttl=700, value=abc700}], [1200, {ttl=1200, value=efg1200}], [1800, {ttl=1800, value=bcd1800}]]))

Now, we can read items by ttl value range, likewise, delete items by ttl value range.

Getting items by ttl value range:

List<Value> startItem = new ArrayList<Value>();
startItem.add(Value.get(100));
startItem.add(Value.get(Value.WILDCARD));

List<Value> endItem = new ArrayList<Value>();
endItem.add(Value.get(1000));
endItem.add(Value.get(Value.WILDCARD));

System.out.println(client.operate(null, myKey, 
            ListOperation.getByValueRange("myListBin1", 
            Value.ListValue.get(startItem), Value.ListValue.get(endItem), 
            ListReturnType.VALUE)));

Output:

(gen:4),(exp:0),(bins:(myListBin1:[[200, {ttl=200, value=cde200}], [700, {ttl=700, value=abc700}]]))

Check full record:

System.out.println("My record: "+ client.get(null, myKey));

Output:

My record: (gen:4),(exp:0),(bins:(myListBin1:[[200, {ttl=200, value=cde200}], [700, {ttl=700, value=abc700}], [1200, {ttl=1200, value=efg1200}], [1800, {ttl=1800, value=bcd1800}]]))

Delete by ttl range:

List<Value> startItem = new ArrayList<Value>();
startItem.add(Value.get(600));
startItem.add(Value.get(Value.WILDCARD));

List<Value> endItem = new ArrayList<Value>();
endItem.add(Value.get(1500));
endItem.add(Value.get(Value.WILDCARD));

client.operate(null, myKey, 
            ListOperation.removeByValueRange("myListBin1", 
            Value.ListValue.get(startItem), Value.ListValue.get(endItem), 
            ListReturnType.VALUE));

System.out.println("My record after ttl range delete: "+ client.get(null, myKey));

Output:

My record after ttl range delete: (gen:5),(exp:0),(bins:(myListBin1:[[200, {ttl=200, value=cde200}], [1800, {ttl=1800, value=bcd1800}]]))