Skip to content

Instantly share code, notes, and snippets.

@danamajid
Created March 12, 2019 17:28
Show Gist options
  • Save danamajid/ae8b0dd0c0d6f068856874cc5eed3902 to your computer and use it in GitHub Desktop.
Save danamajid/ae8b0dd0c0d6f068856874cc5eed3902 to your computer and use it in GitHub Desktop.
NoSQL Design for DynamoDB
// See: https://www.youtube.com/watch?v=HaEPXoXVf2k
const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const dynamoDb = new AWS.DynamoDB.DocumentClient({ api_version: '2012-08-10' });
const TABLE = 'single-table-design';
const GSI1 = 'gsi1';
const GSI1PK = `${GSI1}pk`;
const GSI1SK = `${GSI1}sk`;
const GSI2 = 'gsi2';
const GSI2PK = `${GSI2}pk`;
const GSI2SK = `${GSI2}sk`;
function batchWrite(arr) {
var itemsArray = [];
for (var item of arr) {
itemsArray.push({
PutRequest: {
Item: item
}
});
}
return itemsArray;
}
describe('Queries', function() {
before('Populate some test data', async function() {
const data = [{
// Order 1 information of Customer 1
pk: '[email protected]',
sk: 'order-2018-11-01T12:10:28Z',
items: ['ItemOne', 'ItemTwo'],
status: 'Delivered',
update: '2018-11-01T12:45:28Z',
[GSI1PK]: 'order_1',
[GSI1SK]: '[email protected]',
[GSI2PK]: 'torchys-aus1',
[GSI2SK]: '2018-11-01T12:10:28Z'
}, {
// Customer 1 information
pk: '[email protected]',
sk: 'customer',
fullName: 'Keila Palser',
address: '957 La Follete Center',
city: 'Austin',
state: 'Texas',
email: '[email protected]'
}, {
// Order 2 information of Customer 2
pk: '[email protected]',
sk: 'order-2018-11-01T12:03:37Z',
items: ['ItemOne', 'ItemTwo'],
status: 'En Route',
update: '2018-11-01T12:46:18Z',
[GSI1PK]: 'order_2',
[GSI1SK]: '[email protected]',
[GSI2PK]: 'saltlick-aus1',
[GSI2SK]: 'order-2018-11-01T12:03:37Z'
}, {
// Customer 2 information
pk: '[email protected]',
sk: 'customer',
fullName: 'Umeko Manchester',
address: '90 Arkansas Crossing',
city: 'Austin',
state: 'Texas',
email: '[email protected]'
}, {
// Vendor 1 data
pk: 'torchys-aus1',
sk: 'vendor',
vendorName: 'Torchy\'s Tacos',
address: '762 Utah Drive',
city: 'Austin',
state: 'Texas',
username: 'dgodfroy0',
vendor: 'torchys-aus1'
}, {
// Vendor 2 data
pk: 'saltlick-aus1',
sk: 'vendor',
vendorName: 'Salt Lick',
address: '7750 Dennis Avenue',
city: 'Austin',
state: 'Texas',
username: 'eskelly1',
vendor: 'saltlick-aus1'
}, {
// Driver 1 data
pk: '[email protected]',
sk: 'driver',
name: 'Cornall Sommerton',
address: '3603 Chinook Avenue',
city: 'Austin',
contact: '[email protected]',
status: 'Active',
driver: '[email protected]'
}, {
// GPS 1 data of Driver 1
pk: '[email protected]',
sk: 'gps',
gps: '9vfuvxqkevy',
status: 'assigned',
[GSI1PK]: '9vfu',
[GSI1SK]: 'assigned'
}, {
// GPS 2 data of Driver 1
pk: '[email protected]',
sk: 'gps-05',
gps: '9vfuqsgpeg',
status: 'assigned',
[GSI1PK]: '9vfu',
[GSI1SK]: 'assigned-05min'
}, {
// GPS 3 data of Driver 1
pk: '[email protected]',
sk: 'gps-10',
gps: '9vfvnb9717w',
status: 'assigned',
[GSI1PK]: '9vfv',
[GSI1SK]: 'assigned-10min'
}, {
// Driver 2 data
pk: '[email protected]',
sk: 'driver',
name: 'Field Gress',
address: '7830 Lake View Hill',
city: 'Austin',
contact: '[email protected]',
status: 'Active',
driver: '[email protected]'
}, {
// GPS 1 data of Driver 2
pk: '[email protected]',
sk: 'gps',
gps: '9vfuvxqkevy',
status: 'assigned',
[GSI1PK]: '9vfu',
[GSI1SK]: 'assigned'
}, {
// GPS 2 data of Driver 2
pk: '[email protected]',
sk: 'gps-05',
gps: '9vfuqsgpeg',
status: 'assigned',
[GSI1PK]: '9vfu',
[GSI1SK]: 'assigned-05min'
}, {
// GPS 3 data of Driver 2
pk: '[email protected]',
sk: 'gps-10',
gps: '9vfvnb9717w',
status: 'assigned',
[GSI1PK]: '9vfv',
[GSI1SK]: 'assigned-10min'
}, {
// Item 1 of Order 1 of Driver 1
pk: 'item_1',
sk: '[email protected]',
description: 'Monk Special',
[GSI1PK]: 'order_1',
[GSI1SK]: 'item_1',
[GSI2PK]: '[email protected]',
[GSI2SK]: '2018-11-01T12:10:28Z'
}, {
// Item 2 of Order 1 of Driver 1
pk: 'item_2',
sk: '[email protected]',
description: 'Crossroads',
[GSI1PK]: 'order_1',
[GSI1SK]: 'item_2',
[GSI2PK]: '[email protected]',
[GSI2SK]: '2018-11-01T12:10:28Z'
}, {
// Item 1 of Order 2 of Driver 2
pk: 'item_3',
sk: '[email protected]',
description: 'Brisket',
[GSI1PK]: 'order_2',
[GSI1SK]: 'item_3',
[GSI2PK]: '[email protected]',
[GSI2SK]: '2018-11-01T12:10:28Z'
}, {
// Item 2 of Order 1 of Driver 2
pk: 'item_4',
sk: '[email protected]',
description: 'Pork Ribs',
[GSI1PK]: 'order_2',
[GSI1SK]: 'item_4',
[GSI2PK]: '[email protected]',
[GSI2SK]: '2018-11-01T12:10:28Z'
}];
const params = {
RequestItems: {
[TABLE]: batchWrite(data)
}
};
// await dynamoDb.batchWrite(params).promise();
});
it("#getCustomer(customer: CustomerId)", async function() {
const params = {
TableName: TABLE,
KeyConditionExpression: "#pk = :PK and #sk = :SK",
ExpressionAttributeNames: {
"#pk": "pk",
"#sk": "sk"
},
ExpressionAttributeValues: {
":PK": '[email protected]',
":SK": 'customer'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#listCustomerOrders(customer: CustomerId)", async function() {
const params = {
TableName: TABLE,
KeyConditionExpression: "#pk = :PK and begins_with(#sk, :SK)",
ExpressionAttributeNames: {
"#pk": "pk",
"#sk": "sk"
},
ExpressionAttributeValues: {
":PK": '[email protected]',
":SK": 'order'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#getVendor(vendor: Vendor)", async function() {
const params = {
TableName: TABLE,
KeyConditionExpression: "#pk = :PK and #sk = :SK",
ExpressionAttributeNames: {
"#pk": "pk",
"#sk": "sk"
},
ExpressionAttributeValues: {
":PK": 'saltlick-aus1',
":SK": 'vendor'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#getDriver(driver: DriverId)", async function() {
const params = {
TableName: TABLE,
KeyConditionExpression: "#pk = :PK and #sk = :SK",
ExpressionAttributeNames: {
"#pk": "pk",
"#sk": "sk"
},
ExpressionAttributeValues: {
":PK": '[email protected]',
":SK": 'driver'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#listDriverStatuses(driver: DriverId)", async function() {
const params = {
TableName: TABLE,
KeyConditionExpression: "#pk = :PK and begins_with(#sk, :SK)",
ExpressionAttributeNames: {
"#pk": "pk",
"#sk": "sk"
},
ExpressionAttributeValues: {
":PK": '[email protected]',
":SK": 'gps'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#getOrder(order: OrderId)", async function() {
const params = {
TableName: TABLE,
IndexName: GSI1,
KeyConditionExpression: "#pk = :PK",
ExpressionAttributeNames: {
"#pk": GSI1PK
},
ExpressionAttributeValues: {
":PK": 'order_1'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#getVendorOrders(vendor: VendorId)", async function() {
const params = {
TableName: TABLE,
IndexName: GSI2,
KeyConditionExpression: "#pk = :PK",
ExpressionAttributeNames: {
"#pk": GSI2PK
},
ExpressionAttributeValues: {
":PK": 'saltlick-aus1'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
it("#getDriverOrders(vendor: DriverId)", async function() {
const params = {
TableName: TABLE,
IndexName: GSI2,
KeyConditionExpression: "#pk = :PK",
ExpressionAttributeNames: {
"#pk": GSI2PK
},
ExpressionAttributeValues: {
":PK": '[email protected]'
}
};
const query = await dynamoDb.query(params).promise();
console.log(query);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment