<jupyter_start><jupyter_text>Background Scan OperationHow to run update operations on a namespace in background.This notebook requires Aerospike datbase running locally and that Java kernel has been installed. Visit [Aerospike notebooks repo](https://github.com/aerospike-examples/interactive-notebooks) for additional details and the docker container.  Ensure database is runningThis notebook requires that Aerospike datbase is running.<jupyter_code>import io.github.spencerpark.ijava.IJava;
import io.github.spencerpark.jupyter.kernel.magic.common.Shell;
IJava.getKernelInstance().getMagics().registerMagics(Shell.class);
%sh asd<jupyter_output><empty_output><jupyter_text>Download Aerospike client from POM<jupyter_code>%%loadFromPOM
<dependencies>
  <dependency>
    <groupId>com.aerospike</groupId>
    <artifactId>aerospike-client</artifactId>
    <version>5.0.0</version>
  </dependency>
</dependencies><jupyter_output><empty_output><jupyter_text>Initialize the client and populate test dataInitialize the client and connect to the cluster. The configuration is for Aerospike database running on port 3000 of localhost which is the default. Modify config if your environment is different (Aerospike database running on a different host or different port).<jupyter_code>import com.aerospike.client.AerospikeClient;
import com.aerospike.client.policy.WritePolicy;
import com.aerospike.client.Bin;
import com.aerospike.client.Key;

AerospikeClient client = new AerospikeClient("localhost", 3000);
System.out.println("Initialized the client and connected to the cluster.");

String Namespace = "test";
String Set = "background-scan-update";

// add records with keys "id-1" to "id-10" and 
//    bins bin1 (integer values 1-10) and bin2 (integer values 1000-1010).
WritePolicy wpolicy = new WritePolicy();
wpolicy.sendKey = true;
for (int i = 1; i <= 10; i++) {
    Key key = new Key(Namespace, Set, "id-"+i);
    Bin bin1 = new Bin(new String("bin1"), i);
    Bin bin2 = new Bin(new String("bin2"), 1000+i);
    client.put(wpolicy, key, bin1, bin2);
}
System.out.format("Test data popuated.\n");;<jupyter_output><empty_output><jupyter_text>Scan and Update NamespaceMulti-record updates and deletes can be done in two ways:1. List of bin updates: A list of update operations can be specified, each operating on a bin. The list can be specified in two ways:   1. As part of the Statement object where the query (index) filter is also specified.      Statement::setOps(Operation[] ops]   AerospikeClient::execute(WritePolicy policy, Statement statement)      2. As an operation list parameter in the execute call.      AerospikeClient::execute(WritePolicy policy, Statement statement, Operation[] ops)   2. User Defined Function (UDF): Record-oriented UDFs implement arbitrary logic in a Lua function that is registered with the server and invoked through an API call.      ExecuteTask execute(WritePolicy policy, Statement statement, String packageName, String functionName,                                 Value... functionArgs)<jupyter_code>import com.aerospike.client.AerospikeClient;
import com.aerospike.client.policy.WritePolicy;
import com.aerospike.client.Bin;
import com.aerospike.client.Key;
import com.aerospike.client.query.Statement;
import com.aerospike.client.Operation;
import com.aerospike.client.task.ExecuteTask;

int POLL_INTERVAL_MS = 3000;
int WAIT_TILL_COMPLETE_MS = 100000;

enum ExecOption{STMT, EXEC_ARG, UDF};

WritePolicy wpolicy = new WritePolicy();
wpolicy.sendKey = true;
wpolicy.maxRetries = 0;
// specify TTL here
wpolicy.expiration = -2;

void scanAndUpdate(String seedNodeIp, String namespace, Operation[] ops, ExecOption option) {
    System.out.format("Performing scan-and-update on namespace %s with option %s.\n", namespace, option);
    AerospikeClient client = new AerospikeClient(seedNodeIp, 3000);
    Statement stmt = new Statement();
    ExecuteTask task;
    stmt.setNamespace(namespace);
    switch(option) {
        case STMT:
            stmt.setOperations(ops);
            task = client.execute(wpolicy, stmt); 
            task.waitTillComplete(POLL_INTERVAL_MS, WAIT_TILL_COMPLETE_MS);
            break;
      case EXEC_ARG:
            task = client.execute(wpolicy, stmt, ops); 
            task.waitTillComplete(POLL_INTERVAL_MS, WAIT_TILL_COMPLETE_MS);
            break;
      case UDF:
            // plug in UDFModule, UDFFunction (assumes you have registered the module separately)
            //task = client.execute(wpolicy, stmt, "UDFModule", "UDFFunction"); 
            //task.waitTillComplete(POLL_INTERVAL_MS, WAIT_TILL_COMPLETE_MS);
            break;
      default:
            System.out.format("Error: wrong ExecOption\n");
    }
    client.close();
    System.out.format("Scan-and-update done.\n");;
}
String seedNode = "127.0.0.1";
String namespace = "test";

Operation ops[] = { Operation.touch() };
scanAndUpdate(seedNode, namespace, ops, ExecOption.STMT);
scanAndUpdate(seedNode, namespace, ops, ExecOption.EXEC_ARG);
scanAndUpdate(seedNode, namespace, ops, ExecOption.UDF);<jupyter_output>Performing scan-and-update on namespace test with option STMT.
Scan-and-update done.
Performing scan-and-update on namespace test with option EXEC_ARG.
Scan-and-update done.
Performing scan-and-update on namespace test with option UDF.
Scan-and-update done.<jupyter_text>Clean upFinally close the client connection.<jupyter_code>client.truncate(null, Namespace, null, null);
client.close();
System.out.println("Removed tutorial data and closed server connection.");<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09865229110512129, 'fraction_numerical': 0.011859838274932614, 'mean_word_length': 4.527308838133068, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 30, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '142945', 'license': 'Apache-2.0', 'n_tokens_mistral': 1726, 'n_tokens_neox': 1631, 'n_words': 483, 'path': 'notebooks/java/background_scan_op.ipynb', 'repo_name': 'artanderson/experiments', 'size': '5565'}