SlideShare a Scribd company logo
Copyright © 2016 M/Gateway Developments Ltd
EWD 3 Training Course
Part 25
JavaScript Abstraction of Global Storage:
Global Storage as a
Document Database
Rob Tweed
Director, M/Gateway Developments Ltd
Twitter: @rtweed
Copyright © 2016 M/Gateway Developments Ltd
1-1 correspondence
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
Global Storage
JavaScript Object
Copyright © 2016 M/Gateway Developments Ltd
DocumentNode methods for document database / JSON mapping:
getDocument()
setDocument()
Document Database Methods
Copyright © 2016 M/Gateway Developments Ltd
Instantiate a DocumentNode Object
var doc = new this.documentStore.DocumentNode('myDoc');
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
Copyright © 2016 M/Gateway Developments Ltd
getDocument()
var doc = new this.documentStore.DocumentNode('myDoc');
var myObj = doc.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
creates
Copyright © 2016 M/Gateway Developments Ltd
getDocument()
var doc = new this.documentStore.DocumentNode('myDoc');
var myObj = doc.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
myObj is a standard in-memory JavaScript object
containing a copy of the data that was held within
the DocumentNode's sub-tree of nodes
creates
Copyright © 2016 M/Gateway Developments Ltd
setDocument()
var myObj = { // create the object shown to the right };
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
Copyright © 2016 M/Gateway Developments Ltd
setDocument()
var myObj = { // create the object shown to the right };
var doc = new this.documentStore.DocumentNode('myDoc');
// doesn't yet exist on disk myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
Copyright © 2016 M/Gateway Developments Ltd
setDocument()
var myObj = { // create the object shown to the right };
var doc = new this.documentStore.DocumentNode('myDoc');
doc.setDocument(myObj);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
creates
Copyright © 2016 M/Gateway Developments Ltd
setDocument()
var myObj = { // create the object shown to the right };
var doc = new this.documentStore.DocumentNode('myDoc');
doc.setDocument(myObj);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
}
myDoc is created on disk, containing a copy of
the data that was held within the myObj
object, now mapped to Global Storage nodes
creates
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = dnode.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = dnode.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
e1: {
f1a: 'bar1a',
f2a: 'bar2a'
},
e2: {
f1b: 'bar1b',
f2b: 'bar2b',
f3b: 'bar3b'
}
}
myObj is created from just the sub-tree
of Nodes under myDoc("d")
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
Copyright © 2016 M/Gateway Developments Ltd
Applicable for Any DocumentNode
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
dnode.setDocument(myObj);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myDoc("d","g")=1000
myDoc("d","h2","w1")="foo"
myDoc("d","h2","w2")="bar"
myObj = {
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
Copyright © 2016 M/Gateway Developments Ltd
What if there's an overlap?
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
myObj = {
e2: {
f3b: 'new value',
f4b: 'bar4b'
},
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
?
Copyright © 2016 M/Gateway Developments Ltd
Effectively a merge: new replaces old
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
dnode.setDocument(myObj);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="new value"
myDoc("d","e2","f4b")="bar4b"
myDoc("d","g")=1000
myDoc("d","h2","w1")="foo"
myDoc("d","h2","w2")="bar"
myObj = {
e2: {
f3b: 'new value',
f4b: 'bar4b'
},
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
Copyright © 2016 M/Gateway Developments Ltd
Unless you delete the DocumentNode first
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
dnode.delete();
myObj = {
e2: {
f3b: 'new value',
f4b: 'bar4b'
},
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e1","f1a")="bar1a"
myDoc("d","e1","f2a")="bar2a"
myDoc("d","e2","f1b")="bar1b"
myDoc("d","e2","f2b")="bar2b"
myDoc("d","e2","f3b")="bar3b"
Copyright © 2016 M/Gateway Developments Ltd
Unless you delete the DocumentNode first
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
dnode.delete();
myObj = {
e2: {
f3b: 'new value',
f4b: 'bar4b'
},
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
Copyright © 2016 M/Gateway Developments Ltd
Unless you delete the DocumentNode first
These methods can be applied at any level within an on-disk Document
var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]);
var myObj = { // create the object shown to the right };
dnode.delete();
dnode.setDocument(myObj);
myObj = {
e2: {
f3b: 'new value',
f4b: 'bar4b'
},
g: 1000,
h2: {
w1: 'foo',
w2: 'bar'
}
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d","e2","f3b")="new value"
myDoc("d","e2","f4b")="bar4b"
myDoc("d","g")=1000
myDoc("d","h2","w1")="foo"
myDoc("d","h2","w2")="bar"
Copyright © 2016 M/Gateway Developments Ltd
Advanced features of
getDocument() and setDocument()
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
Arrays in Global Storage are
by convention only, using
consecutively numbered
integers as subscript values
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
Arrays in Global Storage are
by convention only, using
consecutively numbered
integers as subscript values
In legacy applications,
numbering is usually from 1
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
var myObj = myDoc.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
getDocument() maps these to an object
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
?
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
Well, what if item 2 didn't exist on disk?
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
Well, what if item 2 didn't exist on disk?
Element numbers no longer match
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj.d[2]myDoc("d",3)
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
Well, what if item 2 didn't exist on disk?
Which is a problem if we use setDocument() again
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value3"
myDoc("d",3)="value4"
myDoc("d",4)="value5"
myDoc("d",5)="value6"
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
And what if there was a non-integer subscript
breaking the sequence?
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myDoc("d","foo")="bar"
?
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Why is d not mapped to a JavaScript array?
Perhaps only map to array if subscripts are an
un-broken sequence of integers?
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
'foo": "bar"
}}
Why is d not mapped to a JavaScript array?
Perhaps only map to array if subscripts are an
un-broken sequence of integers?
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myDoc("d","foo")="bar"
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
….
"not good"
]
}
Why is d not mapped to a JavaScript array?
Perhaps only map to array if subscripts are an
un-broken sequence of integers?
- this would have big performance implications
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
…. etc
myDoc('d",301839979)="not good!"
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
….
"not good"
]
}
Why is d not mapped to a JavaScript array?
Perhaps only map to array if subscripts are an
un-broken sequence of integers?
- this would have big performance implications
- every subscript value would need checking!
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
…. etc
myDoc('d",301839979)="not good!"
Could be millions to check!
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
var myObj = myDoc.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
getDocument() maps these to an object for performance
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
var myObj = myDoc.getDocument(true);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
If the Global node tree is small, you can force mapping
To an array for continuous integer subscript values starting 0
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.setDocument(myObj)
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
and for guaranteed unambiguous mapping to/from JavaScript objects
Copyright © 2016 M/Gateway Developments Ltd
Using Mapped Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
var myObj = myDoc.getDocument();
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"0": "value0",
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
for (var index in myObj.d) {
console.log('element ' + index: ' + myObj.d[index]);
}
Just have to use a for..in loop
instead of a forEach one
Copyright © 2016 M/Gateway Developments Ltd
What about JavaScript Arrays?
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
JavaScript has a formal array type
eg myObj.d is a JavaScript array
Copyright © 2016 M/Gateway Developments Ltd
What about JavaScript Arrays?
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
JavaScript has a formal array type
eg myObj.d is a JavaScript array
How does setDocument() handle these?
Copyright © 2016 M/Gateway Developments Ltd
setDocument() mapping of Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete();
myDoc.setDocument(myObj);
Copyright © 2016 M/Gateway Developments Ltd
setDocument() mapping of Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value0"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete();
myDoc.setDocument(myObj);
Mapping is to a zero-based sequence of integer subscripts
Copyright © 2016 M/Gateway Developments Ltd
Mapping legacy Global Storage
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete();
myDoc.setDocument(myObj);
What about legacy Mumps integration, where numbering starts from 1?
?
Copyright © 2016 M/Gateway Developments Ltd
Mapping legacy Global Storage
var myDoc = new this.documentStore.DocumentNode('myDoc');
var myObj = myDoc.getDocument();
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
getDocument() mapping will work correctly
Copyright © 2016 M/Gateway Developments Ltd
Mapping legacy Global Storage
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete()
myDoc.setDocument(myObj);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: {
"1": "value1",
"2": "value2",
"3": "value3",
"4": "value4",
"5": "value5",
"6": "value6"
}
}
And the reverse mapping from the object will work correctly
Copyright © 2016 M/Gateway Developments Ltd
setDocument() mapping of Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",0)="value1"
myDoc("d",1)="value2"
myDoc("d",2)="value3"
myDoc("d",3)="value4"
myDoc("d",4)="value5"
myDoc("d",5)="value6"
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete();
myDoc.setDocument(myObj);
But setDocument() mapping from arrays is 0 based
Copyright © 2016 M/Gateway Developments Ltd
setDocument() mapping of Arrays
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
var myDoc = new this.documentStore.DocumentNode('myDoc');
myDoc.delete();
var offset = 1;
myDoc.setDocument(myObj, offset);
..unless you apply an offset as a 2nd argument
Copyright © 2016 M/Gateway Developments Ltd
Mapping Arrays
var myDoc = new this.documentStore.DocumentNode('myDoc');
var offset = 1;
var myObj = myDoc.getDocument(true, offset);
myDoc("a")=123
myDoc("b","c1")="foo"
myDoc("b","c2")="foo2"
myDoc("d",1)="value1"
myDoc("d",2)="value2"
myDoc("d",3)="value3"
myDoc("d",4)="value4"
myDoc("d",5)="value5"
myDoc("d",6)="value6"
If the Global node tree is small, you can force mapping
To an array for continuous integer subscript values starting 0
myObj = {
a: 123,
b: {
c1: 'foo',
c2: 'foo2'
},
d: [
"value1",
"value2",
"value3",
"value4",
"value5",
"value6"
]
}
Copyright © 2016 M/Gateway Developments Ltd
Uniquely Powerful Document Database
• Fine-grained
– ie can be applied at any level within an on-disk
Document
– Save large document using setDocument()
– Retrieve sub-section via getDocument() applied to an
intermediate DocumentNode
– Can even read/write at the individual name/value pair
level anywhere within an on-disk Document
• Using value property of the DocumentNode

More Related Content

What's hot

Agile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collectionAgile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collection
JoEllen Carter
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニング
Yuichi Matsuo
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012
aleks-f
 
Mongo db for C# Developers
Mongo db for C# DevelopersMongo db for C# Developers
Mongo db for C# Developers
Simon Elliston Ball
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
distributed matters
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
Intravert Server side processing for Cassandra
Intravert Server side processing for CassandraIntravert Server side processing for Cassandra
Intravert Server side processing for Cassandra
Edward Capriolo
 
groovy & grails - lecture 2
groovy & grails - lecture 2groovy & grails - lecture 2
groovy & grails - lecture 2
Alexandre Masselot
 
Peggy elasticsearch應用
Peggy elasticsearch應用Peggy elasticsearch應用
Peggy elasticsearch應用
LearningTech
 
"><img src="x">
"><img src="x">"><img src="x">
"><img src="x">
testeracua
 
Mongo db for c# developers
Mongo db for c# developersMongo db for c# developers
Mongo db for c# developers
Simon Elliston Ball
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2
VMware Tanzu
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
NoSQLmatters
 
groovy & grails - lecture 12
groovy & grails - lecture 12groovy & grails - lecture 12
groovy & grails - lecture 12
Alexandre Masselot
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() Output
MongoDB
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
Nikita Popov
 
PHP code examples
PHP code examplesPHP code examples
PHP code examples
programmingslides
 
Cascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUGCascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUG
Matthew McCullough
 
Who moved my pixels?!
Who moved my pixels?!Who moved my pixels?!
Who moved my pixels?!
Mikhail Sosonkin
 
Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)
Sergio Gomez Villamor
 

What's hot (20)

Agile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collectionAgile Testing Days 2018 - API Fundamentals - postman collection
Agile Testing Days 2018 - API Fundamentals - postman collection
 
20110514 mongo dbチューニング
20110514 mongo dbチューニング20110514 mongo dbチューニング
20110514 mongo dbチューニング
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012
 
Mongo db for C# Developers
Mongo db for C# DevelopersMongo db for C# Developers
Mongo db for C# Developers
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
Intravert Server side processing for Cassandra
Intravert Server side processing for CassandraIntravert Server side processing for Cassandra
Intravert Server side processing for Cassandra
 
groovy & grails - lecture 2
groovy & grails - lecture 2groovy & grails - lecture 2
groovy & grails - lecture 2
 
Peggy elasticsearch應用
Peggy elasticsearch應用Peggy elasticsearch應用
Peggy elasticsearch應用
 
"><img src="x">
"><img src="x">"><img src="x">
"><img src="x">
 
Mongo db for c# developers
Mongo db for c# developersMongo db for c# developers
Mongo db for c# developers
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 
groovy & grails - lecture 12
groovy & grails - lecture 12groovy & grails - lecture 12
groovy & grails - lecture 12
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() Output
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 
PHP code examples
PHP code examplesPHP code examples
PHP code examples
 
Cascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUGCascading Through Hadoop for the Boulder JUG
Cascading Through Hadoop for the Boulder JUG
 
Who moved my pixels?!
Who moved my pixels?!Who moved my pixels?!
Who moved my pixels?!
 
Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)Dex Technical Seminar (April 2011)
Dex Technical Seminar (April 2011)
 

Viewers also liked

EWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven IndexingEWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven Indexing
Rob Tweed
 
EWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode ObjectEWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode Object
Rob Tweed
 
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDEWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
Rob Tweed
 
EWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIsEWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIs
Rob Tweed
 
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global StorageEWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
Rob Tweed
 
EWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD ServicesEWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD Services
Rob Tweed
 
EWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsEWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD Applications
Rob Tweed
 
EWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD SessionEWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD Session
Rob Tweed
 
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST ServicesEWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
Rob Tweed
 
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
Rob Tweed
 
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
Rob Tweed
 
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage DatabasesEWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
Rob Tweed
 
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWDEWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
Rob Tweed
 
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORSEWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
Rob Tweed
 
EWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session LockingEWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session Locking
Rob Tweed
 
EWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5b: First Steps in Building a QEWD ApplicationEWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
Rob Tweed
 
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
Rob Tweed
 
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging PatternEWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
Rob Tweed
 
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is StartedEWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
Rob Tweed
 
EWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient ModeEWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient Mode
Rob Tweed
 

Viewers also liked (20)

EWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven IndexingEWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven Indexing
 
EWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode ObjectEWD 3 Training Course Part 20: The DocumentNode Object
EWD 3 Training Course Part 20: The DocumentNode Object
 
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDEWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
 
EWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIsEWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIs
 
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global StorageEWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
 
EWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD ServicesEWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD Services
 
EWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsEWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD Applications
 
EWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD SessionEWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD Session
 
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST ServicesEWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
 
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
 
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
 
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage DatabasesEWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
 
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWDEWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
 
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORSEWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
 
EWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session LockingEWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session Locking
 
EWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5b: First Steps in Building a QEWD ApplicationEWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
EWD 3 Training Course Part 5b: First Steps in Building a QEWD Application
 
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
EWD 3 Training Course Part 13: Putting Everything so far into Practice using ...
 
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging PatternEWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
 
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is StartedEWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
 
EWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient ModeEWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient Mode
 

Similar to EWD 3 Training Course Part 25: Document Database Capabilities

EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
Kiyoshi Sawada
 
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
Kiyoshi Sawada
 
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
Rob Tweed
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
Yasuharu Nakano
 
Ads
AdsAds
Ads
Rosi4
 
An Introduction to Tinkerpop
An Introduction to TinkerpopAn Introduction to Tinkerpop
An Introduction to Tinkerpop
Takahiro Inoue
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
Andrey Karpov
 
JWT - To authentication and beyond!
JWT - To authentication and beyond!JWT - To authentication and beyond!
JWT - To authentication and beyond!
Luís Cobucci
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
inovex GmbH
 
dojo.Patterns
dojo.Patternsdojo.Patterns
dojo.Patterns
Peter Higgins
 
Books
BooksBooks
Books
flaglio
 
Getting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSGetting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJS
MongoDB
 
Need help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdfNeed help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdf
feelinggifts
 
Development By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionDevelopment By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo Edition
Anthony Ferrara
 
jq: JSON - Like a Boss
jq: JSON - Like a Bossjq: JSON - Like a Boss
jq: JSON - Like a Boss
Bob Tiernay
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
DevGAMM Conference
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
Ian Barber
 
Academy PRO: ES2015
Academy PRO: ES2015Academy PRO: ES2015
Academy PRO: ES2015
Binary Studio
 
ts+js
ts+jsts+js
js+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdfjs+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdf
NuttavutThongjor1
 

Similar to EWD 3 Training Course Part 25: Document Database Capabilities (20)

EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
 
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩くEWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
EWD 3トレーニングコース#24 GlobalストレージのJavaScript用抽象化-(e) ドキュメントの末端ノードを渡り歩く
 
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
 
Ads
AdsAds
Ads
 
An Introduction to Tinkerpop
An Introduction to TinkerpopAn Introduction to Tinkerpop
An Introduction to Tinkerpop
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
JWT - To authentication and beyond!
JWT - To authentication and beyond!JWT - To authentication and beyond!
JWT - To authentication and beyond!
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
 
dojo.Patterns
dojo.Patternsdojo.Patterns
dojo.Patterns
 
Books
BooksBooks
Books
 
Getting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSGetting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJS
 
Need help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdfNeed help with questions 2-4. Write assembly code to find absolute v.pdf
Need help with questions 2-4. Write assembly code to find absolute v.pdf
 
Development By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionDevelopment By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo Edition
 
jq: JSON - Like a Boss
jq: JSON - Like a Bossjq: JSON - Like a Boss
jq: JSON - Like a Boss
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
Academy PRO: ES2015
Academy PRO: ES2015Academy PRO: ES2015
Academy PRO: ES2015
 
ts+js
ts+jsts+js
ts+js
 
js+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdfjs+ts fullstack typescript with react and express.pdf
js+ts fullstack typescript with react and express.pdf
 

More from Rob Tweed

QEWD Update
QEWD UpdateQEWD Update
QEWD Update
Rob Tweed
 
Data Persistence as a Language Feature
Data Persistence as a Language FeatureData Persistence as a Language Feature
Data Persistence as a Language Feature
Rob Tweed
 
LNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It TooLNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It Too
Rob Tweed
 
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService FunctionalityEWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
Rob Tweed
 
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.jsEWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
Rob Tweed
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesEWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
Rob Tweed
 
QEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesQEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServices
Rob Tweed
 
QEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It TooQEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It Too
Rob Tweed
 
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Servicesewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
Rob Tweed
 
qewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tierqewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tier
Rob Tweed
 
EWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker ApplianceEWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker Appliance
Rob Tweed
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
Rob Tweed
 
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
Rob Tweed
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
Rob Tweed
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
Rob Tweed
 
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPSEWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
Rob Tweed
 
EWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceEWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a Service
Rob Tweed
 

More from Rob Tweed (17)

QEWD Update
QEWD UpdateQEWD Update
QEWD Update
 
Data Persistence as a Language Feature
Data Persistence as a Language FeatureData Persistence as a Language Feature
Data Persistence as a Language Feature
 
LNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It TooLNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It Too
 
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService FunctionalityEWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
 
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.jsEWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesEWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
 
QEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesQEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServices
 
QEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It TooQEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It Too
 
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Servicesewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
 
qewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tierqewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tier
 
EWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker ApplianceEWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker Appliance
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 4
 
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
EWD 3 Training Course Part 39: Building a React.js application with QEWD, Part 3
 
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
EWD 3 Training Course Part 38: Building a React.js application with QEWD, Part 2
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
 
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPSEWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
 
EWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceEWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a Service
 

Recently uploaded

UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
sjcobrien
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
Drona Infotech
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
XfilesPro
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 

Recently uploaded (20)

UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
Everything You Need to Know About X-Sign: The eSign Functionality of XfilesPr...
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 

EWD 3 Training Course Part 25: Document Database Capabilities

  • 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 25 JavaScript Abstraction of Global Storage: Global Storage as a Document Database Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  • 2. Copyright © 2016 M/Gateway Developments Ltd 1-1 correspondence myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" Global Storage JavaScript Object
  • 3. Copyright © 2016 M/Gateway Developments Ltd DocumentNode methods for document database / JSON mapping: getDocument() setDocument() Document Database Methods
  • 4. Copyright © 2016 M/Gateway Developments Ltd Instantiate a DocumentNode Object var doc = new this.documentStore.DocumentNode('myDoc'); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  • 5. Copyright © 2016 M/Gateway Developments Ltd getDocument() var doc = new this.documentStore.DocumentNode('myDoc'); var myObj = doc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } creates
  • 6. Copyright © 2016 M/Gateway Developments Ltd getDocument() var doc = new this.documentStore.DocumentNode('myDoc'); var myObj = doc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myObj is a standard in-memory JavaScript object containing a copy of the data that was held within the DocumentNode's sub-tree of nodes creates
  • 7. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } }
  • 8. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); // doesn't yet exist on disk myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } }
  • 9. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); doc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } creates
  • 10. Copyright © 2016 M/Gateway Developments Ltd setDocument() var myObj = { // create the object shown to the right }; var doc = new this.documentStore.DocumentNode('myDoc'); doc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } } myDoc is created on disk, containing a copy of the data that was held within the myObj object, now mapped to Global Storage nodes creates
  • 11. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  • 12. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = dnode.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } }
  • 13. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = dnode.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e1: { f1a: 'bar1a', f2a: 'bar2a' }, e2: { f1b: 'bar1b', f2b: 'bar2b', f3b: 'bar3b' } } myObj is created from just the sub-tree of Nodes under myDoc("d")
  • 14. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  • 15. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  • 16. Copyright © 2016 M/Gateway Developments Ltd Applicable for Any DocumentNode These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar" myObj = { g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  • 17. Copyright © 2016 M/Gateway Developments Ltd What if there's an overlap? These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b" myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } ?
  • 18. Copyright © 2016 M/Gateway Developments Ltd Effectively a merge: new replaces old These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="new value" myDoc("d","e2","f4b")="bar4b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar" myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } }
  • 19. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e1","f1a")="bar1a" myDoc("d","e1","f2a")="bar2a" myDoc("d","e2","f1b")="bar1b" myDoc("d","e2","f2b")="bar2b" myDoc("d","e2","f3b")="bar3b"
  • 20. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2"
  • 21. Copyright © 2016 M/Gateway Developments Ltd Unless you delete the DocumentNode first These methods can be applied at any level within an on-disk Document var dnode = new this.documentStore.DocumentNode('myDoc', ['d' ]); var myObj = { // create the object shown to the right }; dnode.delete(); dnode.setDocument(myObj); myObj = { e2: { f3b: 'new value', f4b: 'bar4b' }, g: 1000, h2: { w1: 'foo', w2: 'bar' } } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d","e2","f3b")="new value" myDoc("d","e2","f4b")="bar4b" myDoc("d","g")=1000 myDoc("d","h2","w1")="foo" myDoc("d","h2","w2")="bar"
  • 22. Copyright © 2016 M/Gateway Developments Ltd Advanced features of getDocument() and setDocument()
  • 23. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" Arrays in Global Storage are by convention only, using consecutively numbered integers as subscript values
  • 24. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" Arrays in Global Storage are by convention only, using consecutively numbered integers as subscript values In legacy applications, numbering is usually from 1
  • 25. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() maps these to an object
  • 26. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" ?
  • 27. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6"
  • 28. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? Element numbers no longer match myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj.d[2]myDoc("d",3)
  • 29. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Well, what if item 2 didn't exist on disk? Which is a problem if we use setDocument() again myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value3" myDoc("d",3)="value4" myDoc("d",4)="value5" myDoc("d",5)="value6"
  • 30. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? And what if there was a non-integer subscript breaking the sequence? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myDoc("d","foo")="bar" ?
  • 31. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6"
  • 32. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" 'foo": "bar" }} Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myDoc("d","foo")="bar"
  • 33. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" …. "not good" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? - this would have big performance implications myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" …. etc myDoc('d",301839979)="not good!"
  • 34. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" …. "not good" ] } Why is d not mapped to a JavaScript array? Perhaps only map to array if subscripts are an un-broken sequence of integers? - this would have big performance implications - every subscript value would need checking! myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" …. etc myDoc('d",301839979)="not good!" Could be millions to check!
  • 35. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() maps these to an object for performance
  • 36. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(true); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" If the Global node tree is small, you can force mapping To an array for continuous integer subscript values starting 0 myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] }
  • 37. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.setDocument(myObj) myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } and for guaranteed unambiguous mapping to/from JavaScript objects
  • 38. Copyright © 2016 M/Gateway Developments Ltd Using Mapped Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "0": "value0", "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } for (var index in myObj.d) { console.log('element ' + index: ' + myObj.d[index]); } Just have to use a for..in loop instead of a forEach one
  • 39. Copyright © 2016 M/Gateway Developments Ltd What about JavaScript Arrays? myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } JavaScript has a formal array type eg myObj.d is a JavaScript array
  • 40. Copyright © 2016 M/Gateway Developments Ltd What about JavaScript Arrays? myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } JavaScript has a formal array type eg myObj.d is a JavaScript array How does setDocument() handle these?
  • 41. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj);
  • 42. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value0", "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value0" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); Mapping is to a zero-based sequence of integer subscripts
  • 43. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); What about legacy Mumps integration, where numbering starts from 1? ?
  • 44. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage var myDoc = new this.documentStore.DocumentNode('myDoc'); var myObj = myDoc.getDocument(); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } getDocument() mapping will work correctly
  • 45. Copyright © 2016 M/Gateway Developments Ltd Mapping legacy Global Storage var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete() myDoc.setDocument(myObj); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: { "1": "value1", "2": "value2", "3": "value3", "4": "value4", "5": "value5", "6": "value6" } } And the reverse mapping from the object will work correctly
  • 46. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",0)="value1" myDoc("d",1)="value2" myDoc("d",2)="value3" myDoc("d",3)="value4" myDoc("d",4)="value5" myDoc("d",5)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); myDoc.setDocument(myObj); But setDocument() mapping from arrays is 0 based
  • 47. Copyright © 2016 M/Gateway Developments Ltd setDocument() mapping of Arrays myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] } myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" var myDoc = new this.documentStore.DocumentNode('myDoc'); myDoc.delete(); var offset = 1; myDoc.setDocument(myObj, offset); ..unless you apply an offset as a 2nd argument
  • 48. Copyright © 2016 M/Gateway Developments Ltd Mapping Arrays var myDoc = new this.documentStore.DocumentNode('myDoc'); var offset = 1; var myObj = myDoc.getDocument(true, offset); myDoc("a")=123 myDoc("b","c1")="foo" myDoc("b","c2")="foo2" myDoc("d",1)="value1" myDoc("d",2)="value2" myDoc("d",3)="value3" myDoc("d",4)="value4" myDoc("d",5)="value5" myDoc("d",6)="value6" If the Global node tree is small, you can force mapping To an array for continuous integer subscript values starting 0 myObj = { a: 123, b: { c1: 'foo', c2: 'foo2' }, d: [ "value1", "value2", "value3", "value4", "value5", "value6" ] }
  • 49. Copyright © 2016 M/Gateway Developments Ltd Uniquely Powerful Document Database • Fine-grained – ie can be applied at any level within an on-disk Document – Save large document using setDocument() – Retrieve sub-section via getDocument() applied to an intermediate DocumentNode – Can even read/write at the individual name/value pair level anywhere within an on-disk Document • Using value property of the DocumentNode