Reputation: 51
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
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
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