# Batched commands

Jump to the [Code block](#code-block) for a combined complete example.

[Batched commands](https://aerospike.com/docs/develop/learn/batch) execute against multiple records issued as a single request. Batch reads support `get`, `exists`, `getHeader`, and `operate` requests. Batch writes, introduced in Aerospike 6.0.0, allow write requests against any keys, including updates, deletes, UDFs, and multi-operation `operate` commands.

## Setup

The following examples will use the setup and record structure below to illustrate batch operations in an Aerospike database.

```csharp
using Aerospike.Client;

using System;

using System.Collections;

// Define host configuration

Host config = new Host("127.0.0.1", 3000);

// Establishes a connection to the server

AerospikeClient client = new AerospikeClient(null, config);
```

The record structure:

```asciidoc
Occurred: Integer

Reported: Integer

Posted: Integer

Report: Map

{

    shape: List,

    summary: String,

    city: String,

    state: String,

    duration: String

}

Location: GeoJSON
```

## Policies

Policies are defined for the batch parent policy as well as batch read, batch write, batch delete, and batch UDF operations. [Filter Expressions](https://aerospike.com/docs/develop/client/csharp/usage/atomic/expressions) can be defined within each type of batch operation policy and the batch parent policy, along with other operation specific policies.

```csharp
// Create a new batch policy

BatchPolicy batchPolicy = new BatchPolicy();

batchPolicy.filterExp = Exp.Build(

    // An example that will always return true

    Exp.GT(Exp.Val(2), Exp.Val(1))

);

// Create the batch write policy

BatchWritePolicy batchWritePolicy = new BatchWritePolicy();

batchWritePolicy.filterExp = Exp.Build(

    // An example that will always return true

    Exp.GT(Exp.Val(2), Exp.Val(1))

);
```

## Requests

### Exists

The following example creates an array of ten keys and checks for their existence in the database.

```csharp
// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 4995));

}

// Check if records exist

bool[] exists = client.Exists(batchPolicy, keys);

for (int i = 0; i < exists.Length; i++)

{

    if(!exists[i])

    {

        // Do something

        Console.WriteLine("Key: {0} does not exist", keys[i].userKey);

    }

}

// Close the connection to the server

client.Close();
```

### Read records

The following example creates an array of ten keys and reads the records from the database; returning either the whole record or the specified `report` and `location` bins.

```csharp
// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 1));

}

// Read each whole record

Record[] records = client.Get(batchPolicy, keys);

// Or specifiy bins

// Record[] records = client.Get(batchPolicy, keys, "report", "location");

// Access the records

foreach (Record record in records)

{

    if(record != null)

    {

        // Do something

        Console.WriteLine("Record: {0}\\n", record.ToString().Split("bins:")[1]);

    }

}

// Close the connection to the server

client.Close();
```

### Read commands

The following example creates an array of ten keys and accesses the `city` and `state` map keys to return their respective values from the `report` bin, for each record.

```csharp
// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 1));

}

// Create map key list

string[] mapKeys = {"city", "state"};

// Get 'city' and 'state' from report map for each record

BatchResults batchResult = client.Operate(batchPolicy, batchWritePolicy, keys,

    MapOperation.GetByKeyList("report", mapKeys, MapReturnType.VALUE)

);

// Access the records

foreach (BatchRecord batchRecord in batchResult.records)

{

    Record record = batchRecord.record;

    if(record != null)

    {

        // Do something

        Console.WriteLine("Record: {0}\\n", record.ToString().Split("bins:")[1]);

    }

}

// Close the connection to the server

client.Close();
```

### Read/write commands

The following example creates an array of ten keys and

1.  Defines an [Operation Expression](https://aerospike.com/docs/develop/client/csharp/usage/atomic/expressions#operation-expressions) that compares the `occurred` bin value against the provided value, `20211231`, and verifies the `posted` bin exists to determine the boolean value of the new `recent` key being added to the `report` map.
2.  Returns the `report` bin.

```csharp
// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 1));

}

// Define Operation Expressions

Expression exp = Exp.Build(

    MapExp.Put(MapPolicy.Default, Exp.Val("recent"),

        Exp.And(

            Exp.GT(Exp.IntBin("occurred"), Exp.Val(20211231)),

            Exp.BinExists("posted")

        ),

        Exp.MapBin("report")

    )

);

// Execute the write operation and return the report bin

BatchResults batchResult = client.Operate(batchPolicy, batchWritePolicy, keys,

    ExpOperation.Write("report", exp, ExpWriteFlags.DEFAULT),

    Operation.Get("report")

);

// Access the records

foreach (BatchRecord batchRecord in batchResult.records)

{

    Record record = batchRecord.record;

    if(record != null)

    {

        // Do something

        Console.WriteLine("Record: {0}\\n", record.ToString().Split("bins:")[1]);

    }

}

// Close the connection to the server

client.Close();
```

### Deletes

The following example deletes the records from the database.

```csharp
// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 1));

}

// Delete records passing null to use the default BatchDeletePolicy

BatchResults batchResults = client.Delete(batchPolicy, null, keys);

// Close the connection to the server

client.Close();
```

### Complex batched commands

The following example creates a list of four batch records that each use a differing set of operations.

#### The record with user defined key `4000`

1.  uses the `ops1` array that combines the [Operation Expression](https://aerospike.com/docs/develop/client/csharp/usage/atomic/expressions#operation-expressions).
2.  uses `exp1` which compares the `occurred` bin value against the provided value, `20211231` and verifies the `posted` bin exists to determine the boolean value of the new `recent` key being added to the `report` map.
3.  returns the `report` bin.

#### The record with user defined key `4001`

1.  uses the `ops2` array which contains a read [Operation Expression](https://aerospike.com/docs/develop/client/csharp/usage/atomic/expressions#operation-expressions) that gets the length of the `shape` list from the `report` map and returns the value in a synthetic bin named `numShapes`.

#### The record with user defined key `4002`

1.  uses the `ops3` array which combines a write operation that updates the `posted` bin value, with a map operation that updates the `city` value in the `report` map.
2.  returns both the `posted` and `report` bins.

#### The record with user defined key `4003` is deleted from the database.

```csharp
// Define Operation Expressions

Expression exp1 = Exp.Build(

    MapExp.Put(MapPolicy.Default, Exp.Val("recent"),

        Exp.And(

            Exp.GT(Exp.IntBin("occurred"), Exp.Val(20211231)),

            Exp.BinExists("posted")

        ),

        Exp.MapBin("report")

    )

);

Expression exp2 = Exp.Build(

    ListExp.Size(

        MapExp.GetByKey(MapReturnType.VALUE, Exp.Type.LIST, Exp.Val("shape"), Exp.MapBin("report"))

    )

);

// Define operations

Operation[] ops1 = Operation.Array(

    ExpOperation.Write("report", exp1, ExpWriteFlags.DEFAULT),

    Operation.Get("report")

);

Operation[] ops2 = Operation.Array(ExpOperation.Read("numShapes", exp2, ExpReadFlags.DEFAULT));

Operation[] ops3 = Operation.Array(

    Operation.Put(new Bin("posted", 20201108)),

    MapOperation.Put(MapPolicy.Default, "report", Value.Get("city"), Value.Get("Cedarville")),

    Operation.Get("posted"),

    Operation.Get("report")

);

// Create list of batch records to process

List<BatchRecord> batchRecordList = new List<BatchRecord>();

batchRecordList.Add(new BatchWrite(new Key("sandbox", "ufodata", 4000), ops1));

batchRecordList.Add(new BatchRead(new Key("sandbox", "ufodata", 4001), ops2));

batchRecordList.Add(new BatchWrite(new Key("sandbox", "ufodata", 4002), ops3));

batchRecordList.Add(new BatchDelete(new Key("sandbox", "ufodata", 4003)));

// Proccess the batch

client.Operate(batchPolicy, batchRecordList);

// Access the results

foreach (BatchRecord batchRecord in batchRecordList)

{

    Record record = batchRecord.record;

    if (record != null)

    {

        // Do something

        Console.WriteLine("Record: {0}\\n", record.ToString().Split("bins:")[1]);

    }

}

// Close the connection to the server

client.Close();
```

## Code block

Expand this section for a single code block to execute a batch read/write operation

```csharp
using Aerospike.Client;

using System;

using System.Collections;

// Define host configuration

Host config = new Host("127.0.0.1", 3000);

// Establishes a connection to the server

AerospikeClient client = new AerospikeClient(null, config);

// Create a new batch policy

BatchPolicy batchPolicy = new BatchPolicy();

batchPolicy.filterExp = Exp.Build(

    // An example that will always return true

    Exp.GT(Exp.Val(2), Exp.Val(1))

);

// Create the batch write policy

BatchWritePolicy batchWritePolicy = new BatchWritePolicy();

batchWritePolicy.filterExp = Exp.Build(

    // An example that will always return true

    Exp.GT(Exp.Val(2), Exp.Val(1))

);

// Create batch of keys

Key[] keys = new Key[10];

for (int i = 0; i < 10; i++)

{

    keys[i] = new Key("sandbox", "ufodata", (i + 1));

}

// Define Operation Expressions

Expression exp = Exp.Build(

    MapExp.Put(MapPolicy.Default, Exp.Val("recent"),

        Exp.And(

            Exp.GT(Exp.IntBin("occurred"), Exp.Val(20211231)),

            Exp.BinExists("posted")

        ),

        Exp.MapBin("report")

    )

);

// Execute the write operation and return the report bin

BatchResults batchResult = client.Operate(batchPolicy, batchWritePolicy, keys,

    ExpOperation.Write("report", exp, ExpWriteFlags.DEFAULT),

    Operation.Get("report")

);

// Access the records

foreach (BatchRecord batchRecord in batchResult.records)

{

    Record record = batchRecord.record;

    if(record != null)

    {

        // Do something

        Console.WriteLine("Record: {0}\\n", record.ToString().Split("bins:")[1]);

    }

}

// Close the connection to the server

client.Close();
```