+ All Categories
Home > Technology > A Gremlin ate my graph

A Gremlin ate my graph

Date post: 10-Apr-2017
Category:
Upload: damien-seguy-
View: 739 times
Download: 0 times
Share this document with a friend
51
A gremlin ate my graph Barcelona, Spain, October, 30th 2015
Transcript
Page 1: A Gremlin ate my graph

A gremlin ate my graph

Barcelona, Spain, October, 30th 2015

Page 2: A Gremlin ate my graph

Agenda

Discover the Graph

Steps with a gremlin

The state of the Gremlin

Page 3: A Gremlin ate my graph

Damien Seguy

CTO at Exakat

PHP code as Dataset

Speaker

Page 4: A Gremlin ate my graph
Page 5: A Gremlin ate my graph

What is gremlin?

V : Vertices, or nodes or objects

E : Edges, or links or relations

G : graph, or the dataset

Page 6: A Gremlin ate my graph

The Vertices

g.v represents all the vertices

g.v(1) is one of the nodes

Vertices always have an id

g.v(1) => v(1)

1

Page 7: A Gremlin ate my graph

g.v(1).id => 1 g.v(1).name => apply_filter g.v(1).version => true g.v(1).compat => [4.0, 4.1, 4.2, 4.3]

// non-existing properties g.v(1).isFedAfterMidnight => null

PropertiesGraph is schemaless

apply_filter

Page 8: A Gremlin ate my graph

Vertice discoveryUse map to discover the graph

g.v(2).map => {name=wp_die, leaf=true}

wp_die

Page 9: A Gremlin ate my graph

The Edges

Edges have id, properties

also : start, end and label

g.E represents all the edges

g.e(1) is the edge with Id 1

Page 10: A Gremlin ate my graph

g.e(1) => e(1) g.e(1).map => { } g.e(1).id => 1 g.e(1).label => CALLS

Edge discovery

wp_diewp_ajax_fetch_list CALLS

Edges link the vertices

Page 11: A Gremlin ate my graph

g.e(5).outV => v(2) g.e(6).outV => v(3)

g.e(1).inV => v(4)

Running on the Edges

2

3

4

1

5

6

7

Directed graph

Page 12: A Gremlin ate my graph

g.v(1).out => v(2) v(3)

g.v(1).in => v(4)

g.v(1).both => v(2) v(3)

v(4)

Following Edges

2

3

4

1

5

6

7

g.v(1).inE => e(7)

Page 13: A Gremlin ate my graph

g.v(1).out.id => 2 3

g.v(2).in.in.id => 4

g.v(1).both.id => 2 3

4

Chaining

2

3

4

1

5

6

7

Page 14: A Gremlin ate my graph

Wordpress Calls GraphThe graph of all Wordpress internal function calls

function:name

function:nameCALLS

Page 15: A Gremlin ate my graph

function functionCALLS

Page 16: A Gremlin ate my graph
Page 17: A Gremlin ate my graph

g.v(19).out(‘CALLS’).name => wp_hash_password wp_cache_delete

g.v(19).in(‘CALLS’).name => reset_password wp_check_password

Calling home

wp_set_password

reset_password

wp_hash_password

wp_check_password

wp_cache_delete

CALLS

CALLS

CALLS

CALLS

Page 18: A Gremlin ate my graph

g.v(30).out(‘CALLS’) .retain([g.v(30)]) .name => get_category_parents

Is it Recursive

get_permalink get_category_link

get_category_parentsid : 30

CALLS

CALLSCALLS

Page 19: A Gremlin ate my graph

Is it Recursive

g.v(30).in(‘CALLS’) .retain([g.v(30)]) .name => get_category_parents

get_permalink get_category_link

get_category_parentsid : 30

CALLS

CALLSCALLS

Page 20: A Gremlin ate my graph

g.v(47).out(‘CALLS’).except([g.v(47)]) .out('CALLS').retain([g.v(47)])

.name => wp_trash_comment

Ping-Pong Function

CALLS

wp_trash_commentid: 47

wp_delete_commentid : 148

CALLS

CALLS

CALLS

CALLS

CALLS

CALLS

CALLS

CALLS

Page 21: A Gremlin ate my graph

Up to now

nodes and vertices : basic blocs

in and out (and both) : navigation

except(), retain(), in(‘label’) : filtering

Starting at the vertices

Page 22: A Gremlin ate my graph

Traversing the graph

Finding nodes in the graph that satisfy criteria

Traversing involves listing nodes, following links, applying filters, processing data until all conditions are met

Starting point : g.V and g.E

Page 23: A Gremlin ate my graph

Counting

g.V.count() => 2691 g.E.count() => 9013

function functionCALLS

Page 24: A Gremlin ate my graph

Samplingg.V[0..3].name => do_activate_header do_action wpmu_activate_stylesheet comment_footer_die

g.V[0..3].id => 1 3

5 4

Page 25: A Gremlin ate my graph

Filtering

g.V.has('name','wp_die') => v(25);

wp_die

Page 26: A Gremlin ate my graph

Dying Functions

g.V.out('CALLS') .has('name','wp_die') .count() => 84

???? wp_dieCALLS

Page 27: A Gremlin ate my graph

g.V.out('CALLS') .has('name','wp_die') .name =>

Dying Functions

???? wp_dieCALLS

PROCESSING

wp_die wp_die wp_die wp_die wp_die wp_die wp_die wp_die wp_die

Page 28: A Gremlin ate my graph

g.V.has('name','wp_die') .in('CALLS') .name => wp_ajax_trash_post wp_ajax_delete_post wp_ajax_delete_meta wp_ajax_delete_link wp_ajax_delete_tag wp_ajax_delete_comment wp_ajax_oembed_cache wp_ajax_imgedit_preview we_ajax_fetch_list

Dying Functions

???? wp_dieCALLS

PROCESSING

Page 29: A Gremlin ate my graph

g.V.as('start') .out('CALLS') .has('name','wp_die') .back('start') .name => wp_ajax_trash_post wp_ajax_delete_post wp_ajax_delete_meta wp_ajax_delete_link wp_ajax_delete_tag wp_ajax_delete_comment wp_ajax_oembed_cache wp_ajax_imgedit_preview we_ajax_fetch_list

Dying Functions

???? wp_dieCALLS

PROCESSING

Page 30: A Gremlin ate my graph

Relay Functions

g.V.filter{ it.out('CALLS').count() == 1} .count() => 650

CALLS

CALLS

CALLS

Page 31: A Gremlin ate my graph

Closures

Steps often offer possibility for closure

Closure is between {} , uses ‘it’ as current node, is written in Groovy (or else)

Closure often have a standard default behavior, so they are sometimes stealth

Page 32: A Gremlin ate my graph

Applied to properties

Non standard functions

g.V.filter{ it.name != it.name.toLowerCase()} .count() => 73

Page 33: A Gremlin ate my graph

Leaf and Roots

LEAF

ROOT

g.V.filter{ it.out('CALLS').any() == false} .count() => 407

g.V.filter{ it.in('CALLS').any() == false} .count() => 1304

Page 34: A Gremlin ate my graph

Get Linking Indexg.V.transform{['name':it.name,

'links':it.in('CALLS').count()]}

=> ... {'name':wpmu_signup_stylesheet, 'links':0} {'name':show_blog_form, 'links':7} {'name':validate_blog_form, 'links':3} {'name':show_user_form, 'links':4}

Page 35: A Gremlin ate my graph

Get Called Indexg.V.transform{['name':it.name,

'links':it.in('CALLS').count()] } .order{ it.a.links <=> it.b.links}

=> {'name':get_post, 'links':191} {'name':get_option, 'links':218} {'name':_deprecated_function, 'links':296} {'name':__, 'links':442} {'name':apply_filters, 'links':598}

Page 36: A Gremlin ate my graph

Most linked Function groupCount(m)

m = [:]; g.V.groupCount(m); m; => { v[1] = 1, v[2] = 1, ... v[47] = 1, }

Page 37: A Gremlin ate my graph

Most linked Function groupCount(m){key}{value}

m = [:]; g.V.groupCount(m){it.name} {it.in('CALLS').count()}; m; => { wp_restore_image = 1, press_this_media_buttons = 0, WP_Filesystem = 3, ...

}

Page 38: A Gremlin ate my graph

Most linked Function groupCount(m){key}{value}

m = [:]; g.V.groupCount(m){it.name} {it.in('CALLS').count()};

m.sort{ -it.value }[0..2]; => { apply_filters = 598, __ = 442, _deprecated_function = 296 }

Page 39: A Gremlin ate my graph

Most linked Function

m = [:];n = [:]; g.V.groupCount(m){it.name} {it.in('CALLS').count()} .groupCount(n){it.name} {it.out('CALLS').count()};

n.sort{ -it.value}[0..2]; => { redirect_canonical = 60, export_wp = 47, edit_post = 36 }

Page 40: A Gremlin ate my graph

SideEffect StepssideEffect : emit incoming but allows for side computation

m = [:];n = [:]; g.V.groupCount(m){it.name} {it.in('CALLS').count()} .groupCount(n){it.name} {it.out('CALLS').count()} .count(); => 2692

Page 41: A Gremlin ate my graph

Nature of Stepsfilter step : emit input if condition is satisfied : has(), filter(), retain(), except()

map step : transform input into another object : in(), out(), BOTH()

sideEffect step : emit input but allows for side computation : transform, groupCount, each, sideEffect

Branch and flatMap

Page 42: A Gremlin ate my graph

Lonely Functions

g.V.filter{ it.in('CALLS').any() == false} .filter{ it.out('CALLS').any() == false} .sideEffect{ it.lonely = true; } .count() => 184

SELECT, UPDATE AND COUNT

Page 43: A Gremlin ate my graph

Updating a nodeg.V.sideEffect{ incoming = it.in('CALLS').count(); } .each{ it.setProperty('incoming', incoming); it.setProperty('outgoing', it.out('CALLS').count());

}

Page 44: A Gremlin ate my graph

Updating The Graph// removing deprecated functions

g.V.filter{ it.out('CALLS') .has('name', '_deprecated_function') .any() }

.each{ it.bothE.each{ g.removeEdge(it); }

g.removeVertex(it); }

Page 45: A Gremlin ate my graph

State of Gremlin

Page 46: A Gremlin ate my graph

Apache TinkerPop

http://tinkerpop.incubator.apache.org/

Version : 3.0.2

Page 47: A Gremlin ate my graph

TP2 and TP3

groupCount{}{} map

group().by().by() ValueMap()

Page 48: A Gremlin ate my graph

Vendors

StarDogsqlg

Page 49: A Gremlin ate my graph

Gremlin Variants

Page 50: A Gremlin ate my graph

Gremlin For PHP

https://github.com/PommeVerte/gremlin-php

Get up and running with Tinkerpop 3 and PHP : https://dylanmillikin.wordpress.com/2015/07/20/get-up-and-running-with-tinkerpop-3-and-php/

Using with Neo4j : REST API

Older API : neo4jPHP, rexpro-php

Page 51: A Gremlin ate my graph

Thanks

[email protected] @exakat

http://www.slideshare.net/dseguy/

on the http://2015.phpconference.es//


Recommended