# 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

### Boilerplate

The examples below leverage the following boilerplate to initialize the Aerospike module and connect to a server before executing batch operations.

```js
const Aerospike = await import("aerospike");

const batchType = Aerospike.batchType;

const op = Aerospike.operations;

const maps = Aerospike.maps;

const list = Aerospike.lists;

const exp = Aerospike.exp;

// Set hosts to your server's address and port

const config = { hosts: "YOUR_HOST_ADDRESS:YOUR_PORT" };

// Establishes a connection to the server

const client = await Aerospike.connect(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/node/usage/atomic/expressions) can be defined within each type of batch operation policy and the batch parent policy, along with other operation specific policies.

```js
// Create a new batch policy

const batchPolicy = new Aerospike.BatchPolicy({

  // An example that will always return true

  filterExpression: exp.gt(exp.int(2), exp.int(1)),

});

// Create the batch write policy

const batchWritePolicy = new Aerospike.BatchWritePolicy({

  // An example that will always return true

  filterExpression: exp.gt(exp.int(2), exp.int(1)),

});
```

## Requests

### Exists

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

```js
// Create batch of keys

const keys = Array.from(

  { length: 10 },

  (_, i) => new Aerospike.Key("sandbox", "ufodata", i + 4995),

);

// Check if records exist

const batchResult = await client.batchExists(keys, batchPolicy);

// Access the records

for (const { record } of batchResult) {

  if (result.status !== 0) {

    console.info("Key: %o does not exist", record.key.key);

  }

}
```

### 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.

```js
// Create batch of keys

const batchRecords = Array.from({ length: 10 }, (_, i) => ({

  type: batchType.BATCH_READ,

  key: new Aerospike.Key("sandbox", "ufodata", i + 1),

  readAllBins: true,

  // Can set 'readAllBins' false and specify bins

  // bins: ['report', 'location']

}));

// Read records

const batchResult = await client.batchRead(batchRecords);

// Access the records

for (const { record } of batchResult) {

  console.info("Record bins:", record.bins);

}
```

### 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.

```js
// Create expressions

const city_expr = exp.maps.getByKey(

  exp.binMap("report"),

  exp.str("city"),

  exp.type.STR,

  maps.returnType.VALUE,

);

const state_expr = exp.maps.getByKey(

  exp.binMap("report"),

  exp.str("state"),

  exp.type.STR,

  maps.returnType.VALUE,

);

// Create batch of records

const batchRecords = Array.from({ length: 10 }, (_, i) => ({

  type: batchType.BATCH_READ,

  key: new Aerospike.Key("sandbox", "ufodata", i + 1),

  ops: [

    exp.operations.read("city", city_expr, 0),

    exp.operations.read("state", state_expr, 0),

  ],

}));

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

const batchResult = await client.batchRead(batchRecords);

// Access the records

for (const { record } of batchResult) {

  console.info("Record bins:", record.bins);

}
```

### Read/write operations

The following example creates an array of ten keys and

1.  Defines an [Operation Expression](https://aerospike.com/docs/develop/client/node/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.

```js
// Build the expression

const expr = exp.maps.put(

  exp.binMap("report"),

  exp.and(

    exp.gt(exp.binInt("occurred"), exp.int(20211231)),

    exp.binExists("posted"),

  ),

  exp.str("recent"),

);

// Create batch of keys

const batchRecords = Array.from({ length: 10 }, (_, i) => ({

  type: batchType.BATCH_WRITE,

  key: new Aerospike.Key("sandbox", "ufodata", i + 1),

  ops: [exp.operations.write("report", expr, 0), op.read("report")],

}));

// Execute the write operation and return the report bin

const batchResult = await client.batchWrite(batchRecords);

// Access the records

for (const { record } of batchResult) {

  console.info("Record bins:", record.bins);

}
```

### Deletes

The following example deletes the records from the database.

```js
// Create batch of keys

const keys = Array.from(

  { length: 10 },

  (_, i) => new Aerospike.Key("sandbox", "ufodata", i + 4995),

);

// Delete records

const batchResults = await client.batchRemove(keys);
```

### Complex batched operations

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/node/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/node/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.

```js
// Define Operation Expressions

const write_expr = exp.maps.put(

  exp.binMap("report"),

  exp.and(

    exp.gt(exp.binInt("occurred"), exp.int(20211231)),

    exp.binExists("posted"),

  ),

  exp.str("recent"),

);

const size_expr = exp.lists.size(

  exp.maps.getByKey(

    exp.binMap("report"),

    exp.str("shape"),

    exp.type.LIST,

    maps.returnType.VALUE,

  ),

);

// Create batch of records

const batchRecords = [

  {

    type: batchType.BATCH_WRITE,

    key: new Aerospike.Key("sandbox", "ufodata", 4000),

    ops: [exp.operations.write("report", write_expr, 0), op.read("report")],

  },

  {

    type: batchType.BATCH_READ,

    key: new Aerospike.Key("sandbox", "ufodata", 4001),

    ops: [exp.operations.read("numShapes", size_expr, 0)],

  },

  {

    type: batchType.BATCH_WRITE,

    key: new Aerospike.Key("sandbox", "ufodata", 4002),

    ops: [

      op.write("posted", 20220602),

      maps.put("report", "city", "Cedarville"),

      op.read("posted"),

      op.read("report"),

    ],

  },

  {

    type: batchType.BATCH_REMOVE,

    key: new Aerospike.Key("sandbox", "ufodata", 4003),

  },

];

// Execute the batch

const batchResult = await client.batchWrite(batchRecords);

// Access the records

for (const { record } of batchResult) {

  console.info("Record bins:", record.bins);

}
```

## Code block

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

```js
const Aerospike = await import("aerospike");

const batchType = Aerospike.batchType;

const op = Aerospike.operations;

const maps = Aerospike.maps;

const list = Aerospike.lists;

const exp = Aerospike.exp;

// Set hosts to your server's address and port

const config = { hosts: "YOUR_HOST_ADDRESS:YOUR_PORT" };

// Establishes a connection to the server

const client = await Aerospike.connect(config);

// Define Operation Expressions

const write_expr = exp.maps.put(

  exp.binMap("report"),

  exp.and(

    exp.gt(exp.binInt("occurred"), exp.int(20211231)),

    exp.binExists("posted"),

  ),

  exp.str("recent"),

);

const size_expr = exp.lists.size(

  exp.maps.getByKey(

    exp.binMap("report"),

    exp.str("shape"),

    exp.type.LIST,

    maps.returnType.VALUE,

  ),

);

// Create batch of records

const batchRecords = [

  {

    type: batchType.BATCH_WRITE,

    key: new Aerospike.Key("test", "demo", 4000),

    ops: [exp.operations.write("report", write_expr, 0), op.read("report")],

  },

  {

    type: batchType.BATCH_READ,

    key: new Aerospike.Key("test", "demo", 4001),

    ops: [exp.operations.read("numShapes", size_expr, 0)],

  },

  {

    type: batchType.BATCH_WRITE,

    key: new Aerospike.Key("test", "demo", 4002),

    ops: [

      op.write("posted", 20220602),

      maps.put("report", "city", "Cedarville"),

      op.read("posted"),

      op.read("report"),

    ],

  },

  {

    type: batchType.BATCH_REMOVE,

    key: new Aerospike.Key("test", "demo", 4003),

  },

];

// Execute the batch

const batchResult = await client.batchWrite(batchRecords);

// View the results

for (const { record } of batchResult) {

  console.info("Record bins:", record.bins);

}

await client.close();
```