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}]]))