NoSQL and JavaScript: a love story

4,200
-1

Published on

You may all know that JSON is a subset of JavaScript, but... Did you know that HTML5 implements NoSQL databases? Did you know that JavaScript was recommended for REST by Roy T. Fielding himself? Did you know that map & reduce are part of the native JavaScript API? Did you know that most NoSQL solutions integrate a JavaScript engine? CouchDB, MongoDB, WakandaDB, ArangoDB, OrientDB, Riak.... And when they don't, they have a shell client which does...

The story of NoSQL and JavaScript goes beyond your expectations and open more opportunities than you might imagine... What better match could you find than a flexible and dynamic language for schemaless databases? Isn't, an event-driven language what you were waiting for to manage eventually consistency? When NoSQL doesn't come to JavaScript, JavaScript comes to NoSQL, and does it very well...

Published in: Technology
2 Comments
7 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,200
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
62
Comments
2
Likes
7
Embeds 0
No embeds

No notes for slide

NoSQL and JavaScript: a love story

  1. 1. NoSQL & JavaScript a Love Story! by Alexandre Morgaut TakeOff Conf - Lille 2013
  2. 2. Presentation W3C AC member Wakanda Community Web Architect JS Expert REST Lover NoSQL Fanboy @amorgaut
  3. 3. NoSQL facts
  4. 4. NoSQL FactsMostly SchemalessOften with REST / JSON APIMany store JSONMany embed a JavaScript engine Map / Reduce eventsMany propose a JavaScript Shell
  5. 5. NoSQL FamiliesDocument Store Object store GraphKey-value store Column store
  6. 6. NoSQL FamiliesDocument Store Object store GraphKey-value store Column store
  7. 7. NoSQL FamiliesDocument Store Object store GraphKey-value store Column store
  8. 8. JavaScript facts
  9. 9. JavaScript FactsCreated in 1995Running in Netscape Server in 1996, and then in IISMostly Event-DrivenRecommended in the REST definition in 2000Integrated in CouchDB in 2007HTML5 Datastores appeared in 2009
  10. 10. JavaScript Engines C+ C + SpiderMonkey webkit JavaScriptCore: JSC 3 JIT Compilers: SquirrelFish Extreme: SFX aka Nitro TraceMonkey, (JIT Compiler inside) JägerMonkey, IonMonkey Jav C+ a + Rhino V8 Interpreted or Compiled execution JIT Compiler: CrankShaftNashorn? ? Trident: MSHTML Chakra -> Classic JScript, Managed JScript, & JScript.NET C+ ? + Tamarin Carakan JIT Compiler: NanoJIT -> ActionScript / “ECMAScript 4” Previously: Linear A, Linear B, Futhark
  11. 11. Server-Side JavaScriptSpiderMonkey JavaScriptCore Rhino V8 Trident / Chakra
  12. 12. JavaScript & Databases
  13. 13. JavaScript & DatabasesNetscape Enterprise ServerMicrosoft: JScript, JScript.NET, ActiveXMozilla RhinoJSDBAPE ProjectW3C Web SQL
  14. 14. Netscape Enterprise ServerSQLTable() pool = new DbPool("ORACLE", addr, user, pwd, "", 5, true); connection = pool.connection("A connection"); cursor = connection.cursor("select name from customer");DbPool if ( cursor && (connection.majorErrorCode() == 0) ) { // Get the first row cursor.next(); // Display the values write("<B>Customer Name:</B> " + cursor.name + "<BR>");start/home.html } //Close the cursor cursor.close();Shared Connections Note: Netscape Enterprise Server merged with Javagator to become iPlanet
  15. 15. MS JScript on the server conn = Server.CreateObject("ADODB.Connection");Active Server Page conn.Open(dsn, login, password); reccordset = conn.Execute(sqlQuery); result = []; runat=”server” while (!reccordset.EOF) { result.push({ field1: reccordset("field1"), field2: reccordset("field2")Windows Script Hosting }); rsAuthor2.MoveNext; }.NET conn.Close(); conn = null; Note: JScript is running on Microsoft IIS since 1997
  16. 16. MS JScript in the Browser var connection = new ActiveXObject("ADODB.Connection");    connection.Open(dsn, login, password); var reccordset = new ActiveXObject("ADODB.Recordset");ActiveXObject   reccordset.Open(sqlQuery, connection); reccordset.MoveFirst; while(!reccordset.eof) { only IE } document.write(reccordset.fields(1)); reccordset.movenext;   reccordset.close; connection.close;
  17. 17. Mozilla Rhino importPackage(java.sql); java.lang.Class.forName("org.sqlite.JDBC");Java environment conn = DriverManager.getConnection("jdbc:sqlite:test.db"); stat = conn.createStatement(); resultSet = stat.executeQuery("select * from people;"); while (resultSet.next()){Access to JDBC print( resultSet.getString("name") + " - " + resultSet.getString("occupation") );ex: RingoJS } resultSet.close(); stat.close(); conn.close(); https://developer.mozilla.org/en-US/docs/Rhino
  18. 18. JSDB var db = new ODBC(dsn); var result = db.query("select * from mytable");SpiderMonkey var searcher = new Index; for (var i=1; i <= result.count; i++) { searcher.add(result.get(NAME)); }Shell var i = searcher.find(Mr. Smith); var r = result.getRow(i + 1); writeln(Data for Mr. Smith); writeln(r.toString());JS Server db.close(); http://www.jsdb.org/
  19. 19. APE Project var sql = new Ape.MySQL(ip + ":3306", user, password, db); Ape.registerCmd(foo, true, function(params, cmd) {Real Time Web cmd.user.sendRaw( bar, { hello: world, echo: params.ping Comet } ); sql.query( INSERT INTO table(log) VALUES(" + Web Sockets Ape.MySQL.escape(params.ping) + "), function(res, errorNo) { Ape.log(Inserted + this.getInsertId()); }MySQL ); }); Note: APE means “Ajax Push Engine” http://www.ape-project.org/
  20. 20. W3C Web SQLHTML5 var db = openDatabase(mydb, 1.0, my first db, 2 * 1024 * 1024); db.transaction(function (tx) { Safari tx.executeSql(CREATE TABLE IF NOT EXISTS foo (id unique, text)); tx.executeSql(INSERT INTO foo (id, text) VALUES (1, "synergies")); }); Chrome tx.executeSql(SELECT * FROM foo, [], function (tx, results) { for (var i = 0, len = results.rows.length; i < len; i++) { alert(results.rows.item(i).text); } }); Opera result = x.executeSqlSync(SELECT * FROM foo); for (var i = 0, len = results.rows.length; i < len; i++) { alert(results.rows.item(i).text);Sync / Async } Note: standard paused because current implementations are only based on SQLite http://html5doctor.com/introducing-web-sql-databases/
  21. 21. Data as a Service (DaaS)
  22. 22. Data as a Service Amazon APIs OData APP GData Twitter APIs
  23. 23. Touching the DB heart
  24. 24. Touching the DB HeartKey-Value: Web Storage, RiakDocument: CouchDB, MongoDB, IndexedDBObject: JavaScriptDB, WakandaDBMulti-Model: OrientDB & ArangoDB
  25. 25. Key - Value
  26. 26. Web StorageW3C / WHATWG // set or get items by methods localStorage.setItem("storedItem", "value"); var value = localStorage.getItem("storedItem"); HTML5 // set or get items using the store as a map localStorage.storedItem = value; var value = localStorage.storedItem;local // accessible only for this session var foo = sessionStorage.bar; sessionStorage.bar = foo;session // sync interface when data change, even from other window window.addEventListener("storage", handle_storage, false);eventsNote: Firefox used to propose “globalStorage”, Wakanda implements “user.storage” http://www.w3.org/TR/webstorage/
  27. 27. Riak Buckets {"inputs": "goog", "query": [ {"map": {"language": "javascript", "source": "function(value, keyData, arg){...}" }}, REST / JSON {"reduce": {"language": "javascript", "source": "function(values, arg){...}", "keep": true }} ] } Map / Reduce // Map: compute the daily variance, key it by the month function(value, keyData, arg){ Erlang alternative: var data = Riak.mapValuesJson(value)[0]; var month = value.key.split(-).slice(0,2).join(-); var obj = {}; obj[month] = data.High - data.Low; return [ obj ]; SpiderMonkey } // Reduce: find the maximum variance per month function(values, arg) { return [values.reduce(function(acc, item){ for (var month in item) { acc[month] = acc[month] ? Math.max(item[month], acc[month]) : item[month]; } return acc; })]; }
  28. 28. Document
  29. 29. IndexedDBW3C / WHATWG var request = indexedDB.open("MyTestDatabase", 3); request.onerror = function(event) { // Do something with request.errorCode! HTML5 }; request.onsuccess // Do something = function(event) { with request.result! };Sync / Async request.onupgradeneeded = function(event) { // Update object stores and indices .... }Indexes var objectStore = db.createObjectStore("customers", { keyPath: "ssn" }); objectStore.createIndex("name", "name", { unique: false });Transactions objectStore.add({ ssn: "444-44-4444", name: "Bill", age: 35}); var transaction = db.transaction(["customers"], IDBTransaction.READ_WRITE);Cursors http://www.w3.org/TR/IndexedDB/
  30. 30. CouchDB function(doc) { if (doc.Type == "customer") { emit(doc.LastName, {FirstName: doc.FirstName, Addr: doc.Address}); emit(doc.FirstName, {LastName: doc.LastName, Addr: doc.Address});Views } }JSON* { "total_rows":2, "offset":0, "rows": [Map / Reduce { "id":"64ACF01B05F53ACFEC48C062A5D01D89", "key":"Katz", "value":{"FirstName":"Damien", "Addr":"Charlotte NC"} }, {Erlang alternative: "id":"64ACF01B05F53ACFEC48C062A5D01D89", "key":"Damien", "value":{"LastName":"Katz", "Addr":"Charlotte NC"} }, ] Spidermonkey } Note: CouchDB moved from XML to JSON & JS in 2007* http://wiki.apache.org/couchdb/HTTP_view_API * http://jan.prima.de/~jan/plok/archives/89-CouchDb-updates.html
  31. 31. CouchBaseCouchDB alternative using V8 adding memcache meant to be more scalable http://www.couchbase.com/
  32. 32. MongoDB { text: "lmao! great article!",Spidermonkey } author: kbanker, votes: 2BSON var map = function() { emit(this.author, {votes: this.votes}); };Map / Reduce // Add up all the votes for each key. var reduce = function(key, values) { var sum = 0;REST / JSON values.forEach(function(doc) { sum += doc.votes; }); return {votes: sum}; };REST / JS var op = db.comments.mapReduce(map, reduce, {out: "mr_results"});Shell http://www.mongodb.org/display/DOCS/MapReduce
  33. 33. Object
  34. 34. Persevere JavaScriptDB var d = new Data(); d.test = 12345;Rhino {"id":"generated.js", "sources":[ { "name":"Data", "extends":"Object",REST / JSON "schema":{ "extends":{"$ref":"../Class/Object"}, hello : function() { console.log("hello hi"); },JSON Schema } "prototype":{ } }]JSON Path } curl localhost:8080/Data/1JSON Query ({"id":"1","test":12345}) Data.hello(); // INFO: hi there http://www.sitepen.com/blog/2009/04/20/javascriptdb-perseveres-new-high-performance-storage-engine/
  35. 35. WakandaDB Webkit JavaScriptCore REST / JSON Data Classes auto-updatable accessors john = ds.Person.find("fistName eq John"); events conferences = john.allConferences; JohnJSConferences = conferences.filter("title eq :1", "*JavaScript*"); methods JSAttendeesJohnMet = JSConferences.allPeople; http://wakanda.org/
  36. 36. Multi-Model
  37. 37. ArangoDBV8 actions.defineHttp({ url : "world", context : "api", events callback : function (req, res) { var collection = db._collection(req.parameter.collection); if (collection == null) { ... filters } else { ... } transactions actions.resultOk(req, res, actions.HTTP_OK, result); } });Shell http://www.ape-project.org/
  38. 38. OrientDBrhino // create function getAllCustomerREST / JSON return db.query("select from V")transactions db.begin(); try { " // some code " db.commit()hooks (events) } catch (e) { " } db.rollback();"stored proceduresnew com.orientechnologies.orient.core.record.impl.ODocument(Profile).field(name, Luca).save() http://www.orientdb.org/
  39. 39. Reaching the DB
  40. 40. Reaching the DBmongoose WAF (Wakanda)mongodb-rhino Ext.data.proxy.Wakandariak control arango.clientbackbone-couchdb voltdb-client-nodejsdojox.data.couchDBRestStore redis-node-clientnode-cassandra orientdb-api.js
  41. 41. Thank you!Let’s keep in touch... Client & Server @amorgaut JavaScript APIs http://about.me/amorgaut http://w3.org/community/jseverywhere/ @wakandasoft @jseverywhere http://wakanda.org http://jseverywhere.org
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×