SlideShare a Scribd company logo
1 of 49
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 collectionJoEllen 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 2012aleks-f
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hacksteindistributed 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 CassandraEdward Capriolo
 
Peggy elasticsearch應用
Peggy elasticsearch應用Peggy elasticsearch應用
Peggy elasticsearch應用LearningTech
 
"><img src="x">
"><img src="x">"><img src="x">
"><img src="x">testeracua
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2VMware 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 2015NoSQLmatters
 
MongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB World 2016: Deciphering .explain() Output
MongoDB World 2016: Deciphering .explain() OutputMongoDB
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
 
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 JUGMatthew McCullough
 

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 IndexingRob 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 ObjectRob 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 QEWDRob 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 APIsRob 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 StorageRob 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 ServicesRob 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 ApplicationsRob 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 SessionRob 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 ServicesRob 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 5Rob 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 DatabasesRob 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 QEWDRob 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 CORSRob 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 LockingRob 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 ApplicationRob 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 PatternRob 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 StartedRob 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 ModeRob 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 ObjectsRob Tweed
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyYasuharu Nakano
 
An Introduction to Tinkerpop
An Introduction to TinkerpopAn Introduction to Tinkerpop
An Introduction to TinkerpopTakahiro 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' MistakesAndrey 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 Abwegeninovex GmbH
 
Getting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSGetting Started with MongoDB and NodeJS
Getting Started with MongoDB and NodeJSMongoDB
 
Development By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionDevelopment By The Numbers - ConFoo Edition
Development By The Numbers - ConFoo EditionAnthony Ferrara
 
jq: JSON - Like a Boss
jq: JSON - Like a Bossjq: JSON - Like a Boss
jq: JSON - Like a BossBob 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 giantsIan Barber
 
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.pdfNuttavutThongjor1
 
fullstack typescript with react and express.pdf
fullstack typescript with react and express.pdffullstack typescript with react and express.pdf
fullstack typescript with react and express.pdfNuttavutThongjor1
 

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
 
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
 
fullstack typescript with react and express.pdf
fullstack typescript with react and express.pdffullstack typescript with react and express.pdf
fullstack typescript with react and express.pdf
 

More from Rob Tweed

Data Persistence as a Language Feature
Data Persistence as a Language FeatureData Persistence as a Language Feature
Data Persistence as a Language FeatureRob 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 TooRob 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 FunctionalityRob 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.jsRob 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 ServicesRob Tweed
 
QEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesQEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesRob 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 TooRob 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 ServicesRob 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 TierRob 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 ApplianceRob 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 4Rob 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 3Rob 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 2Rob 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/HTTPSRob 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 ServiceRob 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

Leveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevLeveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevpmgdscunsri
 
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...Splashtop Inc
 
openEuler Community Overview - a presentation showing the current scale
openEuler Community Overview - a presentation showing the current scaleopenEuler Community Overview - a presentation showing the current scale
openEuler Community Overview - a presentation showing the current scaleShane Coughlan
 
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityLarge Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityRandy Shoup
 
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsMUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsUniversity of Antwerp
 
renewable energy renewable energy renewable energy renewable energy
renewable energy renewable energy renewable energy  renewable energyrenewable energy renewable energy renewable energy  renewable energy
renewable energy renewable energy renewable energy renewable energyjeyasrig
 
Enterprise Content Managements Solutions
Enterprise Content Managements SolutionsEnterprise Content Managements Solutions
Enterprise Content Managements SolutionsIQBG inc
 
Practical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfPractical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfICS
 
BATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern
 
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurMinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurPriyadarshini T
 
Boost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made EasyBoost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made Easymichealwillson701
 
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfFlutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfMind IT Systems
 
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...jackiepotts6
 
Steps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic DevelopersSteps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic Developersmichealwillson701
 
Einstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfEinstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfCloudMetic
 
8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.Ritesh Kanjee
 
VuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckVuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckNaval Singh
 
Unlocking the Power of IoT: A comprehensive approach to real-time insights
Unlocking the Power of IoT: A comprehensive approach to real-time insightsUnlocking the Power of IoT: A comprehensive approach to real-time insights
Unlocking the Power of IoT: A comprehensive approach to real-time insightsconfluent
 
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...MyFAA
 

Recently uploaded (20)

Leveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevLeveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDev
 
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...
Splashtop Enterprise Brochure - Remote Computer Access and Remote Support Sof...
 
openEuler Community Overview - a presentation showing the current scale
openEuler Community Overview - a presentation showing the current scaleopenEuler Community Overview - a presentation showing the current scale
openEuler Community Overview - a presentation showing the current scale
 
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityLarge Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
 
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsMUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
 
renewable energy renewable energy renewable energy renewable energy
renewable energy renewable energy renewable energy  renewable energyrenewable energy renewable energy renewable energy  renewable energy
renewable energy renewable energy renewable energy renewable energy
 
Enterprise Content Managements Solutions
Enterprise Content Managements SolutionsEnterprise Content Managements Solutions
Enterprise Content Managements Solutions
 
Practical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdfPractical Advice for FDA’s 510(k) Requirements.pdf
Practical Advice for FDA’s 510(k) Requirements.pdf
 
BATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data Mesh
 
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurMinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
 
Boost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made EasyBoost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made Easy
 
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfFlutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
 
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
 
20140812 - OBD2 Solution
20140812 - OBD2 Solution20140812 - OBD2 Solution
20140812 - OBD2 Solution
 
Steps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic DevelopersSteps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic Developers
 
Einstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfEinstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdf
 
8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.
 
VuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckVuNet software organisation powerpoint deck
VuNet software organisation powerpoint deck
 
Unlocking the Power of IoT: A comprehensive approach to real-time insights
Unlocking the Power of IoT: A comprehensive approach to real-time insightsUnlocking the Power of IoT: A comprehensive approach to real-time insights
Unlocking the Power of IoT: A comprehensive approach to real-time insights
 
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
 

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