Hello,
This email is primarily for Kuppitz and Josh. Kuppitz offered me his attention
yesterday. I explained to him an idea I’ve been working on this week. I’ve been
frustrated lately because emails and IM are so hard to express abstract ideas.
Fortunately, Kuppitz was patient with me. Then he got it. Then he innovated on
it. I was elated.
https://twitter.com/twarko/status/1129117666910674944
<https://twitter.com/twarko/status/1129117666910674944>
Josh was interested in what this was all about. I had to go to leave for
hockey, but I gave him a fast break down. He sorta got the vibe, but wanted to
know more…..
########################################
There is only one type of “tuple.”
{ }#?
The notation says: there are objects, but I don’t know how many of them there
are…..if you want to know more, iterate.
########################################
Let us begin…………..
——————TP4 WITH PROVIDER A——————
g.
{ [V] }#1
There is one object. Thus, what you see is all that I know about this object.
In particular, what I know is that it can be mapped via the bytecode
instruction [V].
Let us apply [V].
{ name:?string | [has,age,?0,?1] [has,id,eq,?0] }#?
There are some number of objects. If you want to know what they are, iterate.
However, I am aware of a feature that they all share. I do know for a fact (by
the way I was designed by my creator ProviderA) that every one of the objects
has a name-key to some string value. Also, two has() bytecode patterns are
available.
Let us apply [hasKey,name].
{ name:?string | [has,age,?0,?1] [has,id,eq,?0] }#?
The instruction didn't match any of the available bytecode patterns. Thus, the
instruction has to evaluated. Did you need to iterate and filter out those that
don’t have a name-key? No. As I told you, I know that every one of the objects
has a name-key.
Let us apply [has,id,eq,1].
{ name:marko, age:29 | [inE] [outE] }#1
There is one thing. It has primitive key/value data — a name and an age.
Let us apply [values,name].
{ marko }#1
That bytecode instruction didn't match any the available bytecode patterns. The
instruction was evaluated and there is one thing: the string “marko.”
We did:
g.V().hasKey(‘name’).hasId(1).values(‘name’)
The query you provided used an index on id. How do we know that? You didn’t
have to iterate all the objects and filter on id. I was able to jump from all
vertices to the one with id=1.
——————TP4 WITH PROVIDER B——————
{ type:person, name:?string, age:?int | [has,name,eq,?0] }?10
There are 10 objects. Some providers can’t determine how many objects there are
without full iteration. But, by the way I was designed, I know. I also know
that all the object have a type:person key/value. I also know they all have a
name-key and int-key with known value types.
What am I?
CREATE TABLE people {
name varchar(100),
age int
}
CREATE INDEX people_name_idx ON people (name);
——————TP4 WITH PROVIDER C——————
g.V().has(‘name’,’marko’).has(‘age’,gt(20)).id()
This is easy. My creator, ProviderC, provides multi-key indices. And when the
database instance was created, a (name,age)-index was created. Also, because
you only want the id of those vertices named marko whose age is greater than
20, I don’t have to manifest the vertices, I can simply get the id out of the
index. This is what I provided for each instruction of your query...
1. { type:graph | [V] }#1
2. { type:vertex | [has,name,eq,?0] [has,age,?0,?1] [id] }#?
3. { type:vertex, label:person, name:marko | [has,age,?0,?1] [id] }#?
4. { type:vertex, label:person, name:marko, age:gt(20) | [id] }#?
5. { type:int }#?
Unlike ProviderA, all the objects in me have a type-key. It is just something I
like to do. Call it my quirk. Thus, on line #2, I know that there are some
number of vertex objects. And do you see my multi-property index there? On line
#3, I know for a fact that every one of those objects has a name:marko entry.
Finally, by line #5, I don’t know how many id-objects there are, but I do know
they are all integers. If you want to know what they are, iterate.
Below are the possible "bytecode pattern”-paths that are available off of the
graph object. At any point through this pattern, you could iterate.
[V]
/ | \
/ [id]\
/ \
[has,name,eq,?0] [has,age,?0,?1]
/ \ / \
/ \ / \
[has,age,?0,?1] [id] [has,name,eq,?0] [id]
| |
[id] [id]
*** In case the diagram above looks weird in your mail client:
https://gist.github.com/okram/f7f20a3c33aa7caca7c28e85fd16be3f
<https://gist.github.com/okram/f7f20a3c33aa7caca7c28e85fd16be3f>
——————TP4 WITH PROVIDER D——————
I support "vertex-centric indices.” For certain queries, I don’t have to
manifest/iterate the incident edges of a vertex to check their key/value pairs.
In particular, I have index all the incident knows-edges by their weight
property. Wanna know who marko knows well? Do this query:
…outE(‘knows’).has(‘weight’,gt(0.85)).inV()
{ label:person, name:marko, age:29 | [outE] [inE] }#1
// [outE]
{ weight:float? | [has,label,eq,?1] [inV] }#20
// [has,label,eq,knows]
{ label:knows, weight:float? | [has,weight,?0,?1] [inV] }#15
// [has,weight,gt,0.85]
{ label:knows, weight:gt(0.85) | [inV] }#15
// [inV]
{ label:person }#15
See. I didn’t create single edge! I do know there are 20 outgoing edges from
marko, but I didn’t manifest them. I then was able to jump to the adjacent
vertices. If you want to know about those, you can iterate….
…label()
{ person }#15
Haha. I don’t have to iterate to solve that. I know that all 15 adjacent
vertices are labeled as ‘person’. I was able to go from v[1] to 15 person
strings without manifesting any intermediate edges or vertices! I’m pretty
freakin’ sweet. How do I know that you ask? I’m an in-memory graph database and
my vertex-centric indices are just Java sets. Its cheap for me to provide
counts, so I do. Most other providers can’t do that. But I can.
——————TP4 WITH PROVIDER E——————
…out(‘knows’).values(‘name’)
==compiles to==>
[outE][has,label,eq,knows][inV][values,name]
{ name:marko, age:29 | [outE] [inE] }#1
// [outE]
{ [has,label,eq,?1] [inV] }#20
// [has,label,eq,knows]
{ label:knows | [inV] }#15
// [inV]
{ label:person | [values,name] }#15
// [values,name]
{ type:string }#15
Did you see that? I didn’t manifest any incident edges nor adjacent vertices
and I was able to give you the name of all the people that marko knows! Can you
guess what features I have?
* Incident edges are indexed by label.
* Certain properties of a vertex can be denormalized (stored locally)
to their adjacent neighbors.
Thanks for reading,
Marko.
http://rredux.com <http://rredux.com/>