The following cells need to be run in order to use the Node kernel and import dependencies
$$.config.awaitExecution = true;
require("child_process").execSync("asd");
const Aerospike = require('aerospike');
const wine = require('./wine-data.json');
const exp = Aerospike.exp;
const op = Aerospike.operations;
const map = Aerospike.maps;
// Define cluster config
const config = {
hosts: '127.0.0.1:3000'
}
console.log('Ready to go!');
The document is an array of objects like the example below:
{
points:"87",
title:"Nicosia 2013 Vulkà Bianco (Etna)",
description:"Aromas include tropical fruit, broom, brimstone and dried herb. The palate isn't overly expressive, offering unripened apple, citrus and dried sage alongside brisk acidity.",
taster: {
name:"Kerin O’Keefe",
twitter_handle:"@kerinokeefe"
},
price:null,
designation:"Vulkà Bianco",
variety:"White Blend",
regions: {
primary: "Etna",
secondary: null
},
province:"Sicily & Sardinia",
country:"Italy",
winery:"Nicosia"
}
The following code will create a record for each wine review in the data set.
const writeRecords = async () => {
let client = await Aerospike.connect(config);
console.log('Writing records...');
return new Promise( async (resolve, reject) => {
// Create write policy
writePolicy = new Aerospike.WritePolicy({
key: Aerospike.policy.key.SEND
});
// Loop through wines and write records
try{
for(let i = 0; i < wine.length; i++){
// Create key
let key = new Aerospike.Key('demo', 'wine-node', i);
// Write the record
await client.put(key, wine[i], [], writePolicy);
}
}
catch(err){
console.log(err);
reject();
}
// Get total objects in set
let response = await client.infoAll('sets/demo/wine-node');
console.log(response[0].info.split(':')[0]);
console.log('Writing records complete');
resolve(client);
});
}
Run the function
writeRecords().then((client) => client.close());
const queryFilter = async () => {
let client = await Aerospike.connect(config);
console.log('Reading with a filter expression...');
return new Promise( async (resolve, reject) => {
// Define query policy
let queryPolicy = new Aerospike.QueryPolicy({
filterExpression: exp.eq(
exp.binStr('country'),
exp.str('Georgia')
)
});
// Create query
let query = client.query('demo', 'wine-node');
// Get query results
let recordStream = await query.foreach(queryPolicy);
// Iterate through the record stream
recordStream.on('error', err => {
console.log(err);
reject();
});
recordStream.on('data', record => {
console.log(record.bins);
});
recordStream.on('end', () => {
console.log('End of records returned');
resolve(client);
});
});
}
Run the function
queryFilter().then((client) => client.close());
Create a string index on the country
.
const country = async () => {
let client = await Aerospike.connect(config);
console.log('Creating country index...');
return new Promise( async (resolve, reject) => {
try{
// Create country index
let indexCountry = await client.createStringIndex({
ns: 'demo', // namespace
set: 'wine-node', // set name
bin: 'country', // bin name
index: 'country_idx', // index name
});
// Wait for the task to complete
indexCountry.wait(1000, () => {
console.log('Country index created');
resolve(client);
});
}
catch(err){
console.log(err);
reject();
}
});
}
Run the function
country().then((client) => client.close());
Create an numeric index on the price
.
const price = async () => {
let client = await Aerospike.connect(config);
console.log('Creating price index...');
return new Promise( async (resolve, reject) => {
try{
// Create price index
let indexPrice = await client.createIntegerIndex({
ns: 'demo', // namespace
set: 'wine-node', // set name
bin: 'price', // bin name
index: 'price_idx', // index name
});
// Wait for the task to complete
indexPrice.wait(1000, () => {
console.log('Price index created\n');
resolve(client);
});
}
catch(err){
console.log(err);
reject();
}
});
}
Run the function
price().then((client) => client.close());
Create a string index on the name
key in the taster
map.
const taster = async () => {
let client = await Aerospike.connect(config);
console.log('Creating taster index...');
return new Promise( async (resolve, reject) => {
try{
// Create taster name index
let indexTaster = await client.createStringIndex({
ns: 'demo', // namespace
set: 'wine-node', // set name
bin: 'taster', // bin name
index: 'taster_idx', // index name
type: Aerospike.indexType.MAPVALUES
});
// Wait for the task to complete
indexTaster.wait(1000, () => {
console.log('Taster index created');
resolve(client);
});
}
catch(err){
console.log(err);
reject();
}
});
}
Run the function
taster().then((client) => client.close());
Return all the wines from Georgia.
const querySindexString = async () => {
let client = await Aerospike.connect(config);
console.log('Reading with a string sindex filter...');
return new Promise( async (resolve, reject) => {
// Create query
let query = client.query('demo', 'wine-node');
// Set query sindex filter
query.where(Aerospike.filter.equal('country', 'Georgia'));
// Get query results
let recordStream = await query.foreach();
// Iterate through the record stream
recordStream.on('error', err => {
console.log(err);
reject();
});
recordStream.on('data', record => {
console.log(record.bins);
});
recordStream.on('end', () => {
console.log('End of records returned \n');
resolve(client);
});
});
}
Run the function
querySindexString().then((client) => client.close());
Get all the with a price between 500 and 1000 USD.
const querySindexNumeric = async () => {
let client = await Aerospike.connect(config);
console.log('Reading with a numeric sindex filter...');
return new Promise( async (resolve, reject) => {
// Create query
let query = client.query('demo', 'wine-node');
// Set query sindex filter
query.where(Aerospike.filter.range('price', 500, 1000));
// Get query results
let recordStream = await query.foreach();
// Iterate through the record stream
recordStream.on('error', err => {
console.log(err);
reject();
});
recordStream.on('data', record => {
console.log(record.bins);
});
recordStream.on('end', () => {
console.log('End of records returned \n');
resolve(client);
});
});
}
Run the function
querySindexNumeric().then((client) => client.close());
Get all the wines from France with more than 95 points and price less than $70
const querySindexWithFilter = async () => {
let client = await Aerospike.connect(config);
console.log('Reading with a sindex and filter expression...');
return new Promise( async (resolve, reject) => {
// Define query policy
let queryPolicy = new Aerospike.QueryPolicy({
filterExpression: exp.and(
exp.gt(exp.binInt('points'), exp.int(95)),
exp.lt(exp.binInt('price'),exp.int(70))
)
});
// Create query
let query = client.query('demo', 'wine-node');
// Set query sindex filter
query.where(Aerospike.filter.equal('country', 'France'));
// Get query results
let recordStream = await query.foreach(queryPolicy);
// Iterate through the record stream
recordStream.on('error', err => {
console.log(err);
reject();
});
recordStream.on('data', record => {
console.log(record.bins);
});
recordStream.on('end', () => {
console.log('End of records returned \n');
resolve(client);
});
});
}
Run the function
querySindexWithFilter().then((client) => client.close());
const newWine = {
"points": 85,
"title": "Barrel Racer 2013 Sauvignon Blanc (Solano County)",
"description": "Practically a liquid fruit salad, this smells and tastes like orange, apple, cantaloupe and banana. The texture is smooth and rounded, rather than crisp. A little buttery flavor comes through on the finish.",
"taster": {
"name":"Jim Gordon",
"twitter_handle": "@gordone_cellars"
},
"price": 18,
"designation": null,
"variety": "Sauvignon Blanc",
"regions": {
"primary": "Solano County",
"secondary": "North Coast"
},
"province": "California",
"country": "US",
"winery": "Barrel Racer"
}
console.log('New wine created');
const addNewWine = async () => {
let client = await Aerospike.connect(config);
console.log('Adding new wine...');
return new Promise( async (resolve, reject) => {
// Create write policy
writePolicy = new Aerospike.WritePolicy({
key: Aerospike.policy.key.SEND
});
// Create key
let key = new Aerospike.Key('demo', 'wine-node', 10001);
try{
// Write record
await client.put(key, newWine, [], writePolicy);
}
catch(err){
console.log(err);
reject();
}
// Verify record
let record = await client.get(key);
console.log(record.bins);
console.log('New wine added \n');
resolve(client);
});
}
Run the function
addNewWine().then((client) => client.close());
Update the price of a wine.
const updateWine = async () => {
let client = await Aerospike.connect(config);
console.log('Updating wine price...');
return new Promise( async (resolve, reject) => {
// Create key
let key = new Aerospike.Key('demo', 'wine-node', 10001);
try{
// Write record
await client.put(key, {price: 24}, [], writePolicy);
}
catch(err){
console.log(err);
reject();
}
// Verify update
let record = await client.select(key, ['price']);
console.log(record.bins);
console.log('Wine price updated \n');
resolve(client);
});
}
Run the function
updateWine().then((client) => client.close());
Update the twitter handle for Lauren Buzzeo on every wine they have tasted.
const updateTaster = async () => {
let client = await Aerospike.connect(config);
console.log('Updating Twitter handle...\n');
return new Promise( async (resolve, reject) => {
// Define the operation
let ops = [map.put('taster', 'twitter_handle', 'laurenbuzzed')]
// Create query
let query = client.query('demo', 'wine-node');
// Set query sindex filter
query.where(Aerospike.filter.contains('taster', 'Lauren Buzzeo', Aerospike.indexType.MAPVALUES));
// Execute the query
let updateJob = await query.operate(ops);
// Wait for the job to complete
updateJob.wait(1000, async () => {
// Create the query
let newQuery = client.query('demo', 'wine-node');
// Set query bins and sindex filter
newQuery.select('taster');
newQuery.where(Aerospike.filter.contains('taster', 'Lauren Buzzeo', Aerospike.indexType.MAPVALUES));
// Get query results
let recordObj = await newQuery.results();
for(let i = 0; i < 5; i++){
console.log(recordObj[i].bins);
}
console.log('\nTwitter handle updated');
resolve(client);
});
});
}
Run the function
updateTaster().then((client) => client.close());
Delete all wines with a points vaule less than 81.
const removeWithFilter = async () => {
let client = await Aerospike.connect(config);
console.log('Deleting records...');
return new Promise( async (resolve, reject) => {
let queryPolicy = new Aerospike.QueryPolicy({
filterExpression: exp.lt(
exp.binInt('points'),
exp.int(81)
)
});
// Create query
let query = client.query('demo', 'wine-node');
// Create ops
let ops = [op.delete()];
// Execute the query
let removeJob = await query.operate(ops, queryPolicy);
// Wait for the job to complete
removeJob.wait(1000, async () => {
console.log('Checking records...');
// Check for deleted records
let newQuery = client.query('demo', 'wine-node');
let recordObj = await newQuery.results(queryPolicy);
if(recordObj.length > 0){
console.log('Records exist');
}
else{
console.log('Records deleted');
resolve(client);
}
});
});
}
Run the function
removeWithFilter().then((client) => client.close());
const cleanup = async () => {
let client = await Aerospike.connect(config);
console.log('Cleaning up...');
return new Promise( async (resolve, reject) => {
try{
// Remove data
await client.truncate('demo', 'wine-node', 0);
console.log('Data removed');
// Remove indexes
await client.indexRemove('demo', 'country_idx');
console.log('Country index removed');
await client.indexRemove('demo', 'price_idx');
console.log('Price index removed');
await client.indexRemove('demo', 'taster_idx');
console.log('Taster index removed');
resolve(client);
}
catch(err){
console.log(err);
reject();
}
});
}
Run the function
cleanup().then((client) => client.close());