Skip to main content

Array

Introduction

Array represents DynamoDB's List data type (marshalled as "L") for DynamoQL.
Every Array type must be defined with its items type.
items can be any DynamoQL type.

Define an Array

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
friendId: {
type: Array,
items: String
}
} as const);

items can also be a union type.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
friendId: {
type: Array,
items: [String, Number]
}
} as const);

Options

- required

boolean which makes attribute as required or optionnal, default is false.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
friendId: {
type: Array,
items: String,
required: true
}
} as const);

- default

To set a default value for an attribute use default option.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
friendId: {
type: Array,
items: String,
default: []
}
} as const);

With this configuration when you put an Item into your table, your Item will contain friendId attribute with an empty array.

default value's type must match defined Array's type.
Otherwise it will throw an error during dev time and runtime.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
friendId: {
type: Array,
items: String,
default: [5] // DynamoQLInvalidTypeException: "friendId[0]" expected to be "S" received "N".
}
} as const);

default can also be a (async) function which accepts one argument (put Item value) and must return an array of defined type.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
friendId: {
type: Array,
items: String,
default: (item: Record<string, any>)=> {
if(item.moderator) {
return ["admin-id"]
}
return []
}
}
} as const);

- validate

validate option allows you to manually validate provided value in put and update commands.
To return an error you should return a string which explains value invalidity. Any other returned value is considered as valid.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
friendId: {
type: Array,
items: String,
validate: (self: string[])=> {
if(self.length > 10) {
return "Error: Can not have more than 10 friends."
}
}
}
} as const);

- set

To modify a value before storing it use set option.
set (async) function accepts 3 arguments:

  1. self provided value.
  2. item entier put Item object.
  3. setterInfo an optionnal value provided inside in put, batchPut, batchWrite, transactWrite command's options.

set will not be called if attribute doesn't exists in put Item object.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
friendId: {
type: Array,
items: String,
set: (self: string[], item: Record<string, any>, setterInfo?: any)=> {

if(item.moderator && setterInfo?.someCondition) {
return ["a-1234567890"]
}

return self
}
}
} as const);

- get

When reteving an Item we can transform field's value with get option.

get (async) function accepts 3 arguments:

  1. self retrieved value.
  2. item entier retrieved Item object.
  3. getterInfo an optionnal value provided inside get, batchGet, transactGet, query, scan command's options.

get can return anything.
get will not be called if attribute doesn't exists in stored Item.

import { Schema } from "dynamoql";
import { randomUUID } from "crypto";

const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
friendId: {
type: Array,
items: String,
get: (self: string[], item: Record<string, any>, getterInfo?: any)=> {
return self.map(x=> doSomething(x))
}
}
} as const);
info

get returned value's type affects Item type when retriving Item(s) from DynamoDB.

- description

add any information to the Schema for your personal usage.

Condition expression

Condition expression are not part of Schema but they are based on your defined Schema.
They are used in various DynamoDB operations to check for some condition(s).
DynamoQL supports all DynamoDB Condition expression.

- equals

{
friendId: ["admin"]
}

or

{
friendId: {
$eq: ["admin"]
}
}

- not equals

{
friendId: {
$neq: ["admin"]
}
}

- attribute exists

$exists can be true or false.

{
friendId: {
$exists: true
}
}

- includes

Checks if stored array contains provided value.

{
friendId: {
$includes: "admin"
}
}

- array length

Checks for stored array's length.

{
friendId: {
$size: 1
}
}

$size can also be any valid numeric comparison operator.

{
friendId: {
$size: {
$gt: 0
}
}
}

Possible operators are $eq, $neq, $gt, $gte, $lt, $lte, $in, $between.

- attribute type

Checks for stored attribute type.

{
friendId: {
$type: Array
}
}

$type can be String, Number, Boolean, Null, Buffer, Object, Array, or {type: Set, items: String | Number | Buffer }

- child condition

Sometimes we need to verify a condition on a specific item of array.
Accessing child element is possible with 2 styles.

DynamoDB style

{
"friendId[9]": "admin"
}

DynamoQL style

{
friendId: {
"[9]": "admin"
}
}

Please refer to your defined Array items type for more condition.
In our example it will be String

- AND

Checks for multiple conditions. Condition is valid if ALL specified conditions are satisfied.

{
friendId: {
$and: [
{
$size: 6
},
{
$includes: "admin"
}
]
}
}

shorthand style

{
friendId: {
$size: 6,
$includes: "admin"
}
}

- OR

Checks for multiple conditions. Condition is valid if at least one of specified conditions is satisfied.

{
friendId: {
$or: [
{
$size: 6
},
{
$includes: "admin"
}
]
}
}

- NOT

Condition is valid if specified condition is NOT satisfied.

{
friendId: {
$not: {
$includes: "admin"
}
}
}

$not accepts any Condition expression.

When multiple conditions are provided inside $not: {} they are considered as $and condition.

{
friendId: {
$not: {
$size: 6,
$includes: "admin"
}
}
}

longhand equivalent is:

{
friendId: {
$not: {
$and: [
{
$size: 6
},
{
$includes: "admin"
}
]
}
}
}

Update expressions

Like Condition expression, Update expressions are not part of Schema, but they are based on defined Schema.

Update expressions are used in update, transactUpdate and transactWrite operations.

DynamoQL supports all DynamoDB update operations.

- set

$set replaces stored array by provided array.

{
friendId: {
$set: ["admin"]
}
}

shorthand version is

{
friendId: ["admin"]
}

To update a specific item in stored array provide item index in your key path:

{
"friendId[0]": "admin"
}

or with DynamoQL style

{
friendId: {
"[0]": "admin"
}
}

Please refer to your defined Array items type for more operations.

- if not exists

$ifNotExists sets provided array if attribute do not exists in stored item.
$ifNotExists dont affects Condition expression and is attribute specific.
If attribute exists, stored value stays unchanged.

{
friendId: {
$ifNotExists: ["admin"]
}
}

- push

inserts provided value(s) at the end of stored array.

{
friendId: {
$push: "admin"
}
}

push multiple values.

{
friendId: {
$push: ["admin", "guest"]
}
}

- unshift

inserts provided value(s) at the beginning of stored array.

{
friendId: {
$unshift: "admin"
}
}

unshift multiple values.

{
friendId: {
$unshift: ["admin", "guest"]
}
}

- remove

removes item(s) from stored array by index or indices.

{
friendId: {
$remove: 4
}
}

remove multiple items.

{
friendId: {
$remove: [1, 4]
}
}
info

You can not use multiple operations on the same attribute.
This is DynamoDB limitation.

{
friendId: {
$remove: 4,
$push: "admin"
}
}
info

During update operations provided values are validated against defined Schema, with TLS for better developper experience and during runtime for type safety.

- update array element

Like with Child condition you can update a specific item in array with its index.

{
"friendId[4]": "admin"
}

or

{
friendId: {
"[4]": "admin"
}
}

Please refer to your defined Array items type for more update operations.
In our example it will be String