Full Stack Development with
Node.js and NoSQL
Matthew Groves (@mgroves)
#couchbase
©2016 Couchbase Inc. 2
Where am I?
‱ Austin Node.JS User Group
‱ http://www.meetup.com/noders/
©2016 Couchbase Inc. 3
Who am I?
‱ Matthew D. Groves
‱ Developer Advocate for Couchbase
‱ @mgroves onTwitter
‱ Podcast and blog: http://crosscuttingconcerns.com
‱ “I am not an expert, but I am an enthusiast.” – Alan Stevens
©2016 Couchbase Inc. 4
Couchbase and CouchDB
Couchbase is to CouchDB
as
MySQL is to SQL Server
©2016 Couchbase Inc. 5
Tweet something, get a sticker!
Use #Couchbase
Tweet something interesting you’ve learned.
Tweet a picture.
I’ve got stickers!
Full Stack Development with
Node.js and NoSQL
Matthew Groves (@mgroves)
#couchbase
The Part of the Stack With Software
Application Development and
Infrastructure Management with Node.js
and Second Generation Non-Relational
Document Databases Which by theWay
Actually Do Have a SQL-like Query
Language
©2016 Couchbase Inc. 8
Full Stack Developer
©2016 Couchbase Inc. 9
Application Stacks
©2016 Couchbase Inc. 10
NoSQL: Flexible JSON Schema
©2016 Couchbase Inc. 11
Where is NoSQL a Good Fit?
Low-latency Critical
High Throughput or Large Numbers of Users
Unknown Demand with Sudden growth
Predominantly Direct Document Access
Read / Mixed / Write-heavy Workloads
Traditional Business Applications
Transaction-heavy Apps
Legacy Hardware
Full ACID support
Web / Mobile / IoT Legacy Business Apps
©2016 Couchbase Inc. 12
Where is NoSQL a Good Fit?
http://info.couchbase.com/15Q1TopTenUC.html
©2016 Couchbase Inc. 13
What is Couchbase?
Couchbase is a distributed operational database that enables you to
develop with agility and operate at any scale.
Managed Cache Key-Value Store Document Database Embedded Database Sync Management
©2016 Couchbase Inc. 14
Agility
Easier, Faster Development Flexible Data Modeling Powerful Querying
SQL Integration & Migration Big Data Integration Mobile / IoT
©2016 Couchbase Inc. 15
Scale
Elastic Scalability Consistent High Performance Always-on Availability
Multi-Data Center Deployment Simple, Powerful Administration Enterprise Grade Security
©2016 Couchbase Inc. 16
Couchbase Developer
©2016 Couchbase Inc. 17
Couchbase and Big Data
©2016 Couchbase Inc. 18
Couchbase Server – Single Node Architecture
©2016 Couchbase Inc. 19
Simplified Administration: Console
©2016 Couchbase Inc. 20
Simplified Administration: RESTful API
©2016 Couchbase Inc. 21
Accessing Data: Key access using Document ID
©2016 Couchbase Inc. 22
Accessing Data:Views using static queries
©2016 Couchbase Inc. 23
Accessing Data: Queries using N1QL
©2016 Couchbase Inc. 24
The Couchbase Node.js SDK
 Uses the Couchbase C library
 Compatible with Node.js frameworks
 Available on NPM
©2016 Couchbase Inc. 25
Building Applications with Node.js SDK
//including the Node.js dependency
var Couchbase = require("couchbase");
//connecting to a Couchbase cluster
var cluster = new Couchbase.Cluster("couchbase://localhost");
//opening a bucket in the cluster
var myBucket = cluster.openBucket("travel-sample", "password");
//preparing N1ql
var myQuery = Couchbase.N1qlQuery();
//creating and saving a Document
var document = {
firstname: "Matt",
lastname: "Groves"
};
myBucket.insert("my-key", document, function(error, result) {});
©2016 Couchbase Inc. 26
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
©2016 Couchbase Inc. 27
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
©2016 Couchbase Inc. 28
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
©2016 Couchbase Inc. 29
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
©2016 Couchbase Inc. 30
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
©2016 Couchbase Inc. 31
Node.js
function query(sql, done) {
var queryToRun = myQuery.fromString(sql);
myBucket.query(queryToRun, function(error, result) {
if(error) {
console.log(“ERROR: “, error);
done(error, null);
return;
}
done(null, result);
return;
});
}
Demo (web)
©2016 Couchbase Inc. 33
The CEAN Stack
©2016 Couchbase Inc. 34
Stack Design
AngularJS
Client Frontend
Node.js/Express
Server Backend
©2016 Couchbase Inc. 35
Multiple Frontends & One Backend
©2015 Couchbase Inc. 36
The Angular 2 Frontend
©2016 Couchbase Inc. 37
Get all documents
// list.component.ts
export class ListComponent implements OnInit {
public people: Array<any>;
public constructor(private http: Http) { this.people = []; }
public ngOnInit() {
this.http.get("http://localhost:3000/api/getAll")
.map(result => result.json())
.subscribe(results => {
this.people = results;
}, error => {
console.error(error);
});
}
}
©2016 Couchbase Inc. 38
Get all documents
<!-- list.component.html -->
<tbody>
<tr *ngFor="let person of people">
<td>{{person.firstname}}</td>
<td>{{person.lastname}}</td>
<td>{{person.email}}</td>
<td>
<a [routerLink]="['/item', person.id]">edit</a>
|
<a href="#" (click)="delete(person.id)">delete</a>
</td>
</tr>
</tbody>
©2016 Couchbase Inc. 39
Save a document
<!-- item.component.html -->
<form>
<div class="form-group">
<label for="firstname">First Name</label>
<input type="text" class="form-control" id="firstname" placeholder="First Name" [(ngModel)]="person.firstname">
</div>
<div class="form-group">
<label for="lastname">Last Name</label>
<input type="text" class="form-control" id="lastname" placeholder="Last Name" [(ngModel)]="person.lastname">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" class="form-control" id="email" placeholder="Email" [(ngModel)]="person.email">
</div>
<button type="button" class="btn btn-danger" [routerLink]="['/']">Cancel</button>
<button type="button" class="btn btn-success" (click)="save()">Save</button>
</form>
©2016 Couchbase Inc. 40
Save a document
// item.component.ts
export class ItemComponent implements OnInit {
public person: any;
public save() {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this.http.post("http://localhost:3000/api/save", JSON.stringify(this.person), options)
.map(result => result.json())
.subscribe(results => {
this.location.back();
}, error => {
console.error(error);
});
}
}
©2015 Couchbase Inc. 41
The Node.js Backend
©2016 Couchbase Inc. 42
Node.js Configuration
// config.json
{
"couchbase": {
"server": "localhost:8091",
"bucket": "default"
}
}
©2016 Couchbase Inc. 43
Node.js Configuration
// app.js file
var express = require("express");
var bodyParser = require("body-parser");
var couchbase = require("couchbase");
var path = require("path");
var config = require("./config");
var app = express();
©2016 Couchbase Inc. 44
Node.js Configuration
// app.js continued...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
module.exports.bucket =
(new couchbase.Cluster(config.couchbase.server))
.openBucket(config.couchbase.bucket);
app.use(express.static(path.join(__dirname, "public")));
var routes = require("./routes/routes.js")(app);
var server = app.listen(3000, function () {
console.log("Listening on port %s...", server.address().port);
});
©2016 Couchbase Inc. 45
Node.js Create or Update Endpoint
// routes.js
app.post("/api/create", function(req, res) {
if(!req.body.firstname) {
return res.status(400).send({"status": "error", "message": ”First Name?"});
}
// 

RecordModel.save(req.body, function(error, result) {
if(error) {
return res.status(400).send(error);
}
res.send(result);
});
});
©2016 Couchbase Inc. 46
Node.js Get Document Endpoint
// routes.js continued...
app.get("/api/get", function(req, res) {
if(!req.query.document_id) {
return res.status(400).send({"status": "error", "message": ”Document ID?"});
}
RecordModel.getByDocumentId(req.query.document_id, function(error, result) {
if(error) {
return res.status(400).send(error);
}
res.send(result);
});
});
©2016 Couchbase Inc. 47
Node.js Delete Endpoint
// routes.js continued...
app.post("/api/delete", function(req, res) {
if(!req.body.document_id) {
return res.status(400).send({"status": "error", "message": ”ID?"});
}
RecordModel.delete(req.body.document_id, function(error, result) {
if(error) {
return res.status(400).send(error);
}
res.send(result);
});
});
©2016 Couchbase Inc. 48
Node.js Upsert Document Function
// recordmodel.js
RecordModel.save = function(data, callback) {
var jsonObject = {
type: "user",
firstname: data.firstname,
lastname: data.lastname,
email: data.email
}
var documentId = data.document_id ? data.document_id : uuid.v4();
db.upsert(documentId, jsonObject, function(error, result) {
if(error) {
return callback(error, null);
}
callback(null, {message: "success", data: result});
});
}
©2016 Couchbase Inc. 49
Couchbase JSON Document
©2016 Couchbase Inc. 50
Node.js Get Document with N1QL Function
// recordmodel.js continued

RecordModel.getByDocumentId = function(documentId, callback) {
var statement = "SELECT firstname, lastname, email " +
"FROM `" + config.couchbase.bucket + "` AS users " +
"WHERE META(users).id = $1";
var query = N1qlQuery.fromString(statement);
db.query(query, [documentId], function(error, result) {
if(error) {
return callback(error, null);
}
callback(null, result);
});
};
©2016 Couchbase Inc. 51
Node.js Delete Document Function
// recordmodel.js continued...
RecordModel.delete = function(documentId, callback) {
db.remove(documentId, function(error, result) {
if(error) {
callback(error, null);
return;
}
callback(null, {message: "success", data: result});
});
};
©2015 Couchbase Inc. 52
More Complex Node.js Queries
©2016 Couchbase Inc. 53
Node.jsTravel Sample
FlightPath.findAll = function(from, to, callback) {
var statement = "SELECT faa AS fromAirport, geo " +
"FROM `" + config.couchbase.bucket + "` r" +
"WHERE airportname = $1 " +
"UNION SELECT faa AS toAirport, geo " +
"FROM `" + config.couchbase.bucket + "` r" +
"WHERE airportname = $2";
var query = N1qlQuery.fromString(statement);
db.query(query, [from, to], function(error, result) {
if(error) {
return callback(error, null);
}
callback(null, result);
});
};
©2016 Couchbase Inc. 54
Node.jsTravel Sample
FlightPath.findAll = function(queryFrom, queryTo, leave, callback) {
var statement = "SELECT r.id, a.name, s.flight, s.utc, " +
" r.sourceairport, r.destinationairport, r.equipment " +
"FROM `" + config.couchbase.bucket + "` r" +
"UNNEST r.schedule s " +
"JOIN `" + config.couchbase.bucket + "` a ON KEYS r.airlineid " +
"WHERE r.sourceairport = $1 AND r.destinationairport = $2 AND s.day = $3 ”
"ORDER BY a.name";
var query = N1qlQuery.fromString(statement);
db.query(query, [queryFrom, queryTo, leave], function(error, result) {
if(error) {
return callback(error, null);
}
callback(null, result);
});
};
©2016 Couchbase Inc. 55
Node.js Sample Applications
https://github.com/couchbaselabs/try-cb-nodejs
https://github.com/couchbaselabs/restful-angularjs-nodejs
©2016 Couchbase Inc. 56
Couchbase N1QLTutorial
http://query.pub.couchbase.com/tutorial/
©2015 Couchbase Inc. 57
Ottoman ODM
https://www.npmjs.com/package/ottoman
©2016 Couchbase Inc. 58
Ottoman Model
var RecordModel = ottoman.model("Record", {
firstname: {type: "string”},
lastname: {type: "string"},
email: {type: "string"},
created_at: {type: “Date”, default: Date.now}
});
©2016 Couchbase Inc. 59
Ottoman Saving
var myRecord = new RecordModel({
firstname: "Matt",
lastname: "Groves",
email: "matthew.groves@couchbase.com"
});
myRecord.save(function(error) {
if(error) {
// Error here
}
// Success here
});
©2016 Couchbase Inc. 60
Ottoman Finding
RecordModel.find({}, function(error, result) {
if(error) {
// Error here
}
// Array of results here
});
©2015 Couchbase Inc. 61
Couchbase Mobile
©2016 Couchbase Inc. 62
Couchbase Lite
Embedded NoSQL Database
Sync Gateway
Secure Synchronization
Couchbase
Server
Cloud NoSQL Database
Couchbase Mobile
©2016 Couchbase Inc. 63
NativeScript Demo
https://github.com/couchbaselabs/nativescript-couchbase
©2016 Couchbase Inc. 64
Couchbase, everybody!
http://couchbase.com/connect
http://info.couchbase.com/Connect16_Livestream_Registration.html
©2016 Couchbase Inc. 65
Where do you find us?
‱ developer.couchbase.com
‱ blog.couchbase.com
‱ forums.couchbase.com
‱ @couchbasedev
‱ #couchbase
‱ @mgroves
‱ @couchbase

Full stack development with Node and NoSQL - Austin Node.JS Group - October 2016

  • 1.
    Full Stack Developmentwith Node.js and NoSQL Matthew Groves (@mgroves) #couchbase
  • 2.
    ©2016 Couchbase Inc.2 Where am I? ‱ Austin Node.JS User Group ‱ http://www.meetup.com/noders/
  • 3.
    ©2016 Couchbase Inc.3 Who am I? ‱ Matthew D. Groves ‱ Developer Advocate for Couchbase ‱ @mgroves onTwitter ‱ Podcast and blog: http://crosscuttingconcerns.com ‱ “I am not an expert, but I am an enthusiast.” – Alan Stevens
  • 4.
    ©2016 Couchbase Inc.4 Couchbase and CouchDB Couchbase is to CouchDB as MySQL is to SQL Server
  • 5.
    ©2016 Couchbase Inc.5 Tweet something, get a sticker! Use #Couchbase Tweet something interesting you’ve learned. Tweet a picture. I’ve got stickers!
  • 6.
    Full Stack Developmentwith Node.js and NoSQL Matthew Groves (@mgroves) #couchbase
  • 7.
    The Part ofthe Stack With Software Application Development and Infrastructure Management with Node.js and Second Generation Non-Relational Document Databases Which by theWay Actually Do Have a SQL-like Query Language
  • 8.
    ©2016 Couchbase Inc.8 Full Stack Developer
  • 9.
    ©2016 Couchbase Inc.9 Application Stacks
  • 10.
    ©2016 Couchbase Inc.10 NoSQL: Flexible JSON Schema
  • 11.
    ©2016 Couchbase Inc.11 Where is NoSQL a Good Fit? Low-latency Critical High Throughput or Large Numbers of Users Unknown Demand with Sudden growth Predominantly Direct Document Access Read / Mixed / Write-heavy Workloads Traditional Business Applications Transaction-heavy Apps Legacy Hardware Full ACID support Web / Mobile / IoT Legacy Business Apps
  • 12.
    ©2016 Couchbase Inc.12 Where is NoSQL a Good Fit? http://info.couchbase.com/15Q1TopTenUC.html
  • 13.
    ©2016 Couchbase Inc.13 What is Couchbase? Couchbase is a distributed operational database that enables you to develop with agility and operate at any scale. Managed Cache Key-Value Store Document Database Embedded Database Sync Management
  • 14.
    ©2016 Couchbase Inc.14 Agility Easier, Faster Development Flexible Data Modeling Powerful Querying SQL Integration & Migration Big Data Integration Mobile / IoT
  • 15.
    ©2016 Couchbase Inc.15 Scale Elastic Scalability Consistent High Performance Always-on Availability Multi-Data Center Deployment Simple, Powerful Administration Enterprise Grade Security
  • 16.
    ©2016 Couchbase Inc.16 Couchbase Developer
  • 17.
    ©2016 Couchbase Inc.17 Couchbase and Big Data
  • 18.
    ©2016 Couchbase Inc.18 Couchbase Server – Single Node Architecture
  • 19.
    ©2016 Couchbase Inc.19 Simplified Administration: Console
  • 20.
    ©2016 Couchbase Inc.20 Simplified Administration: RESTful API
  • 21.
    ©2016 Couchbase Inc.21 Accessing Data: Key access using Document ID
  • 22.
    ©2016 Couchbase Inc.22 Accessing Data:Views using static queries
  • 23.
    ©2016 Couchbase Inc.23 Accessing Data: Queries using N1QL
  • 24.
    ©2016 Couchbase Inc.24 The Couchbase Node.js SDK  Uses the Couchbase C library  Compatible with Node.js frameworks  Available on NPM
  • 25.
    ©2016 Couchbase Inc.25 Building Applications with Node.js SDK //including the Node.js dependency var Couchbase = require("couchbase"); //connecting to a Couchbase cluster var cluster = new Couchbase.Cluster("couchbase://localhost"); //opening a bucket in the cluster var myBucket = cluster.openBucket("travel-sample", "password"); //preparing N1ql var myQuery = Couchbase.N1qlQuery(); //creating and saving a Document var document = { firstname: "Matt", lastname: "Groves" }; myBucket.insert("my-key", document, function(error, result) {});
  • 26.
    ©2016 Couchbase Inc.26 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 27.
    ©2016 Couchbase Inc.27 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 28.
    ©2016 Couchbase Inc.28 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 29.
    ©2016 Couchbase Inc.29 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 30.
    ©2016 Couchbase Inc.30 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 31.
    ©2016 Couchbase Inc.31 Node.js function query(sql, done) { var queryToRun = myQuery.fromString(sql); myBucket.query(queryToRun, function(error, result) { if(error) { console.log(“ERROR: “, error); done(error, null); return; } done(null, result); return; }); }
  • 32.
  • 33.
    ©2016 Couchbase Inc.33 The CEAN Stack
  • 34.
    ©2016 Couchbase Inc.34 Stack Design AngularJS Client Frontend Node.js/Express Server Backend
  • 35.
    ©2016 Couchbase Inc.35 Multiple Frontends & One Backend
  • 36.
    ©2015 Couchbase Inc.36 The Angular 2 Frontend
  • 37.
    ©2016 Couchbase Inc.37 Get all documents // list.component.ts export class ListComponent implements OnInit { public people: Array<any>; public constructor(private http: Http) { this.people = []; } public ngOnInit() { this.http.get("http://localhost:3000/api/getAll") .map(result => result.json()) .subscribe(results => { this.people = results; }, error => { console.error(error); }); } }
  • 38.
    ©2016 Couchbase Inc.38 Get all documents <!-- list.component.html --> <tbody> <tr *ngFor="let person of people"> <td>{{person.firstname}}</td> <td>{{person.lastname}}</td> <td>{{person.email}}</td> <td> <a [routerLink]="['/item', person.id]">edit</a> | <a href="#" (click)="delete(person.id)">delete</a> </td> </tr> </tbody>
  • 39.
    ©2016 Couchbase Inc.39 Save a document <!-- item.component.html --> <form> <div class="form-group"> <label for="firstname">First Name</label> <input type="text" class="form-control" id="firstname" placeholder="First Name" [(ngModel)]="person.firstname"> </div> <div class="form-group"> <label for="lastname">Last Name</label> <input type="text" class="form-control" id="lastname" placeholder="Last Name" [(ngModel)]="person.lastname"> </div> <div class="form-group"> <label for="email">Email</label> <input type="text" class="form-control" id="email" placeholder="Email" [(ngModel)]="person.email"> </div> <button type="button" class="btn btn-danger" [routerLink]="['/']">Cancel</button> <button type="button" class="btn btn-success" (click)="save()">Save</button> </form>
  • 40.
    ©2016 Couchbase Inc.40 Save a document // item.component.ts export class ItemComponent implements OnInit { public person: any; public save() { let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); this.http.post("http://localhost:3000/api/save", JSON.stringify(this.person), options) .map(result => result.json()) .subscribe(results => { this.location.back(); }, error => { console.error(error); }); } }
  • 41.
    ©2015 Couchbase Inc.41 The Node.js Backend
  • 42.
    ©2016 Couchbase Inc.42 Node.js Configuration // config.json { "couchbase": { "server": "localhost:8091", "bucket": "default" } }
  • 43.
    ©2016 Couchbase Inc.43 Node.js Configuration // app.js file var express = require("express"); var bodyParser = require("body-parser"); var couchbase = require("couchbase"); var path = require("path"); var config = require("./config"); var app = express();
  • 44.
    ©2016 Couchbase Inc.44 Node.js Configuration // app.js continued... app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); module.exports.bucket = (new couchbase.Cluster(config.couchbase.server)) .openBucket(config.couchbase.bucket); app.use(express.static(path.join(__dirname, "public"))); var routes = require("./routes/routes.js")(app); var server = app.listen(3000, function () { console.log("Listening on port %s...", server.address().port); });
  • 45.
    ©2016 Couchbase Inc.45 Node.js Create or Update Endpoint // routes.js app.post("/api/create", function(req, res) { if(!req.body.firstname) { return res.status(400).send({"status": "error", "message": ”First Name?"}); } // 
 RecordModel.save(req.body, function(error, result) { if(error) { return res.status(400).send(error); } res.send(result); }); });
  • 46.
    ©2016 Couchbase Inc.46 Node.js Get Document Endpoint // routes.js continued... app.get("/api/get", function(req, res) { if(!req.query.document_id) { return res.status(400).send({"status": "error", "message": ”Document ID?"}); } RecordModel.getByDocumentId(req.query.document_id, function(error, result) { if(error) { return res.status(400).send(error); } res.send(result); }); });
  • 47.
    ©2016 Couchbase Inc.47 Node.js Delete Endpoint // routes.js continued... app.post("/api/delete", function(req, res) { if(!req.body.document_id) { return res.status(400).send({"status": "error", "message": ”ID?"}); } RecordModel.delete(req.body.document_id, function(error, result) { if(error) { return res.status(400).send(error); } res.send(result); }); });
  • 48.
    ©2016 Couchbase Inc.48 Node.js Upsert Document Function // recordmodel.js RecordModel.save = function(data, callback) { var jsonObject = { type: "user", firstname: data.firstname, lastname: data.lastname, email: data.email } var documentId = data.document_id ? data.document_id : uuid.v4(); db.upsert(documentId, jsonObject, function(error, result) { if(error) { return callback(error, null); } callback(null, {message: "success", data: result}); }); }
  • 49.
    ©2016 Couchbase Inc.49 Couchbase JSON Document
  • 50.
    ©2016 Couchbase Inc.50 Node.js Get Document with N1QL Function // recordmodel.js continued
 RecordModel.getByDocumentId = function(documentId, callback) { var statement = "SELECT firstname, lastname, email " + "FROM `" + config.couchbase.bucket + "` AS users " + "WHERE META(users).id = $1"; var query = N1qlQuery.fromString(statement); db.query(query, [documentId], function(error, result) { if(error) { return callback(error, null); } callback(null, result); }); };
  • 51.
    ©2016 Couchbase Inc.51 Node.js Delete Document Function // recordmodel.js continued... RecordModel.delete = function(documentId, callback) { db.remove(documentId, function(error, result) { if(error) { callback(error, null); return; } callback(null, {message: "success", data: result}); }); };
  • 52.
    ©2015 Couchbase Inc.52 More Complex Node.js Queries
  • 53.
    ©2016 Couchbase Inc.53 Node.jsTravel Sample FlightPath.findAll = function(from, to, callback) { var statement = "SELECT faa AS fromAirport, geo " + "FROM `" + config.couchbase.bucket + "` r" + "WHERE airportname = $1 " + "UNION SELECT faa AS toAirport, geo " + "FROM `" + config.couchbase.bucket + "` r" + "WHERE airportname = $2"; var query = N1qlQuery.fromString(statement); db.query(query, [from, to], function(error, result) { if(error) { return callback(error, null); } callback(null, result); }); };
  • 54.
    ©2016 Couchbase Inc.54 Node.jsTravel Sample FlightPath.findAll = function(queryFrom, queryTo, leave, callback) { var statement = "SELECT r.id, a.name, s.flight, s.utc, " + " r.sourceairport, r.destinationairport, r.equipment " + "FROM `" + config.couchbase.bucket + "` r" + "UNNEST r.schedule s " + "JOIN `" + config.couchbase.bucket + "` a ON KEYS r.airlineid " + "WHERE r.sourceairport = $1 AND r.destinationairport = $2 AND s.day = $3 ” "ORDER BY a.name"; var query = N1qlQuery.fromString(statement); db.query(query, [queryFrom, queryTo, leave], function(error, result) { if(error) { return callback(error, null); } callback(null, result); }); };
  • 55.
    ©2016 Couchbase Inc.55 Node.js Sample Applications https://github.com/couchbaselabs/try-cb-nodejs https://github.com/couchbaselabs/restful-angularjs-nodejs
  • 56.
    ©2016 Couchbase Inc.56 Couchbase N1QLTutorial http://query.pub.couchbase.com/tutorial/
  • 57.
    ©2015 Couchbase Inc.57 Ottoman ODM https://www.npmjs.com/package/ottoman
  • 58.
    ©2016 Couchbase Inc.58 Ottoman Model var RecordModel = ottoman.model("Record", { firstname: {type: "string”}, lastname: {type: "string"}, email: {type: "string"}, created_at: {type: “Date”, default: Date.now} });
  • 59.
    ©2016 Couchbase Inc.59 Ottoman Saving var myRecord = new RecordModel({ firstname: "Matt", lastname: "Groves", email: "matthew.groves@couchbase.com" }); myRecord.save(function(error) { if(error) { // Error here } // Success here });
  • 60.
    ©2016 Couchbase Inc.60 Ottoman Finding RecordModel.find({}, function(error, result) { if(error) { // Error here } // Array of results here });
  • 61.
    ©2015 Couchbase Inc.61 Couchbase Mobile
  • 62.
    ©2016 Couchbase Inc.62 Couchbase Lite Embedded NoSQL Database Sync Gateway Secure Synchronization Couchbase Server Cloud NoSQL Database Couchbase Mobile
  • 63.
    ©2016 Couchbase Inc.63 NativeScript Demo https://github.com/couchbaselabs/nativescript-couchbase
  • 64.
    ©2016 Couchbase Inc.64 Couchbase, everybody! http://couchbase.com/connect http://info.couchbase.com/Connect16_Livestream_Registration.html
  • 65.
    ©2016 Couchbase Inc.65 Where do you find us? ‱ developer.couchbase.com ‱ blog.couchbase.com ‱ forums.couchbase.com ‱ @couchbasedev ‱ #couchbase ‱ @mgroves ‱ @couchbase