fereshte
fereshte

Reputation: 51

Aerospike List operation : how to delete one item from all list bins in a set

I have a Set that have two Bins(pId is long , values is list) and list index is applied on values. Now i want to remove specify value from values list of all records.

I used ListOperation.removeByValue and it's working but it's not fast when records size is more than 100000 records.it's take about 11 seconds to do loop operation.

WritePolicy clientWritePolicy = new WritePolicy();
clientWritePolicy.commitLevel = CommitLevel.COMMIT_MASTER;
clientWritePolicy.recordExistsAction = RecordExistsAction.UPDATE;
clientWritePolicy.expiration = 300;
              
Statement statement = new Statement();
statement.setIndexName("values_index");
statement.setNamespace("test");
statement.setSetName("setTest");
               
statement.setFilter(Filter.contains("values", IndexCollectionType.LIST, value));
QueryPolicy queryPolicy = new QueryPolicy();
RecordSet recSet = client.query(queryPolicy, statement);
    
recSet.forEach(rec->{
   client.operate(clientWritePolicy, rec.key,ListOperation.removeByValue("values",Value.get(value), ListReturnType.NONE));
   });

How can i optimize this code?is it any other solution like use UDF?

update 1: I wrote below function in lua file:

function removeListByValue(rec,v)
    local l = list()
    for value in list.iterator(rec["values"]) do
        if(value ~= v) then
             list.append(l, value)
        end
     end
     rec["values"] = l;
     aerospike:update( rec );
end

and run it from java client :

WritePolicy clientWritePolicy = new WritePolicy();
clientWritePolicy.commitLevel = CommitLevel.COMMIT_MASTER;
clientWritePolicy.recordExistsAction = RecordExistsAction.UPDATE;
clientWritePolicy.expiration = 300;

Statement statement = new Statement();
statement.setIndexName("values_index");
statement.setNamespace("test");
statement.setSetName("setTest");

statement.setFilter(Filter.contains("values", IndexCollectionType.LIST, value));
client.execute(clientWritePolicy, statement, "luaPackage", "removeListByValue",Value.get(value));
       

it seems that UDF takes more time to update or remove records.it's about 29 seconds for 200 records.

Upvotes: 2

Views: 577

Answers (2)

fereshte
fereshte

Reputation: 51

Thanks @pgupta. I checked your answer on Aerospike Server 5.6.0.7 :

    WritePolicy clientWritePolicy = new WritePolicy();
    clientWritePolicy.commitLevel = CommitLevel.COMMIT_MASTER;
    clientWritePolicy.recordExistsAction = RecordExistsAction.REPLACE;
    clientWritePolicy.expiration = 300;
    Statement statement = new Statement();
    statement.setIndexName("values_index");
    statement.setNamespace("test");
    statement.setSetName("setTest");
    statement.setFilter(Filter.contains("values", IndexCollectionType.LIST, value));
    Operation[] operations = new Operation[1];
    operations[0]= ListOperation.removeByValue("values",value, ListReturnType.NONE);
    client.execute(clientWritePolicy, statement,operations);

it works.Thank You.

Upvotes: 3

pgupta
pgupta

Reputation: 5415

You can apply operations (your ListOperation) in execute instead of using a UDF. You can specify operations in the Statement object using setOperations() and then just use execute(wPolicy, statement).

e.g.
Operation[] operations = new Operation[1];
operations[0]= ListOperation.removeByValue(.... 
stmt.setOperations(operations);
WritePolicy wPolicyScan = new WritePolicy();
ExecuteTask et = client.execute(wPolicyScan, stmt)

Java API:

execute(WritePolicy policy, Statement statement, Operation... operations) Apply operations on records that match the background query statement filter

Upvotes: 5

Related Questions