├── .gitignore ├── .startup ├── fraud ├── northwind └── startup.order ├── LICENSE ├── README.md ├── documentation-examples ├── CSV │ ├── authorBook │ │ ├── author.csv │ │ ├── authorBook.csv │ │ ├── authorBookMappingCSV.groovy │ │ ├── book.csv │ │ ├── readme.md │ │ ├── runDGL.sh │ │ └── schema.groovy │ ├── edgeProperty │ │ ├── edgePropertyMapping.groovy │ │ ├── person.csv │ │ ├── personKnowsEdges.csv │ │ ├── runDGL.sh │ │ └── schema.groovy │ ├── fridgeItemCOMPKEY │ │ ├── fridgeItem.csv │ │ ├── fridgeItemEdges.csv │ │ ├── fridgeItemMappingCOMPKEY.groovy │ │ ├── ingredients.csv │ │ ├── readme.md │ │ ├── runDGL.sh │ │ └── schema.groovy │ ├── gzip_test │ │ ├── gzipMapping.groovy │ │ ├── readme.md │ │ ├── recipes.csv.gz │ │ └── runDGL.sh │ ├── meals.csv │ ├── readme.md │ └── reviewerRating │ │ ├── readme.md │ │ ├── recipes.csv.gz │ │ ├── recipes_complete.csv │ │ ├── reviewerRatingMapping.groovy │ │ ├── reviewerRatings.csv.gz │ │ ├── reviewers.csv.gz │ │ ├── runDGL.sh │ │ └── schema.groovy ├── GEO │ └── 5.1 │ │ ├── data │ │ └── geodetic.csv │ │ ├── geodetic-data.groovy │ │ ├── geodetic-map-script.groovy │ │ ├── geodetic-queries.groovy │ │ ├── geodetic-schema.groovy │ │ ├── graphloader_command.txt │ │ ├── readme.md │ │ └── verify.groovy ├── JSON │ ├── authorBookMap_JSON.groovy │ ├── data │ │ ├── edges │ │ │ └── authorBook.json │ │ ├── loader.log │ │ └── vertices │ │ │ ├── author.json │ │ │ └── book.json │ ├── graphloader_command.txt │ ├── readme.md │ ├── schema.groovy │ └── verify.groovy ├── MISC │ ├── filePattern │ │ ├── filePatternCSVMap.groovy │ │ ├── filePatternJSONMap.groovy │ │ ├── filePatternMULTMap.groovy │ │ ├── filePatternQUESTMap.groovy │ │ ├── filePatternRANGEMap.groovy │ │ ├── queries.groovy │ │ ├── readme.md │ │ ├── runDGL.sh │ │ └── schema.groovy │ ├── filter_map_flatmap │ │ ├── filterData.csv │ │ ├── filterMap.groovy │ │ ├── filterQueries.groovy │ │ ├── filterSchema.groovy │ │ ├── flatmapData.csv │ │ ├── flatmapMap.groovy │ │ ├── flatmapQueries.groovy │ │ ├── flatmapSchema.groovy │ │ ├── graphloaderFilter.txt │ │ ├── graphloaderFlatmap.txt │ │ ├── mapData.csv │ │ ├── mapMap.groovy │ │ ├── mapQueries.groovy │ │ ├── mapSchema.csv │ │ └── readme.md │ ├── metaProperty │ │ ├── data.groovy │ │ ├── queries.groovy │ │ ├── readme.md │ │ └── schema.groovy │ ├── multiCard │ │ ├── authorCity.csv │ │ ├── multiCardMap.groovy │ │ ├── query.groovy │ │ ├── readme.md │ │ ├── runDGL.sh │ │ └── schema.groovy │ └── readme.md └── readme.md ├── dse-graph-frame ├── README.md ├── Spark-shell-notes.scala ├── build.sbt ├── friends-graph.groovy └── src │ └── main │ └── scala │ └── com │ └── datastax │ └── bdp │ └── graphframe │ └── example │ ├── RandomReceiver.scala │ └── StreamingExample.scala ├── entity-resolution ├── README.md ├── build.sbt ├── data │ ├── add_1.csv │ ├── add_2.csv │ └── initial.csv ├── schema.groovy └── src │ └── main │ └── scala │ └── com │ └── datastax │ └── bdp │ └── er │ ├── EntityRecognitionExample.scala │ └── streaming │ ├── RandomReceiver.scala │ └── StreamingExample.scala ├── fraud ├── JavaFluentAPI │ ├── README.md │ ├── build-example.sh │ ├── pom.xml │ ├── run-example.sh │ └── src │ │ └── main │ │ └── java │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── datastax │ │ └── fraud │ │ └── FraudSample.java ├── README.md ├── data │ ├── chargebacks.csv │ ├── creditCards.csv │ ├── customerAddresses.csv │ ├── customerAddresses.json │ ├── customerChargebacks.csv │ ├── customerOrders.csv │ ├── customerSessions.csv │ ├── customers.csv │ ├── devices.csv │ ├── orderChargebacks.csv │ ├── orders.csv │ └── sessions.csv ├── fraud-mapping.groovy ├── fraud-mapping.groovy.config ├── mysql-import-data.sql ├── mysql-schema.sql ├── pom.xml ├── schema.groovy ├── src │ └── main │ │ └── scala │ │ └── com │ │ └── datastax │ │ └── fraud │ │ └── DataImport.scala └── studio │ ├── 1_of_4_Creating_DSE_Graph_and_Graph_Schema.studio-nb.tar │ ├── 1_of_4_Creating_DSE_Graph_and_Graph_Schema_2018-11-20_18_23_12.studio-nb.tar │ ├── 2_of_4_Populating_and_Traversing_the_Graph.studio-nb.tar │ ├── 2_of_4_Populating_and_Traversing_the_Graph_2018-11-20_18_23_15.studio-nb.tar │ ├── 3_of_4_Indexing_and_Traversing_Graph_Data.studio-nb.tar │ ├── 3_of_4_Indexing_and_Traversing_Graph_Data_2018-11-20_18_23_06.studio-nb.tar │ ├── 4_of_4_Fraud_Scenarios.studio-nb.tar │ └── 4_of_4_Fraud_Scenarios_2018-11-20_18_23_04.studio-nb.tar ├── killrvideo ├── .gitignore ├── README.md ├── data │ ├── friendship.dat │ ├── genres.dat │ ├── movies.dat │ ├── persons.dat │ ├── ratings.dat │ └── users.dat ├── dsl │ ├── dotnet │ │ ├── KillrVideo.sln │ │ ├── KillrVideo │ │ │ ├── App │ │ │ │ └── App.cs │ │ │ ├── Dsl │ │ │ │ ├── Enrichment.cs │ │ │ │ ├── Genre.cs │ │ │ │ ├── KillrVideoGraphTraversalExtensions.cs │ │ │ │ ├── KillrVideoGraphTraversalSourceExtensions.cs │ │ │ │ ├── Kv.cs │ │ │ │ ├── Recommender.cs │ │ │ │ └── __KillrVideo.cs │ │ │ └── KillrVideo.csproj │ │ └── README.asciidoc │ ├── java │ │ ├── README.asciidoc │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── killrvideo │ │ │ │ ├── Enrichment.java │ │ │ │ ├── Genre.java │ │ │ │ ├── KV.java │ │ │ │ ├── KillrVideoApp.java │ │ │ │ ├── KillrVideoTraversalDsl.java │ │ │ │ ├── KillrVideoTraversalSourceDsl.java │ │ │ │ └── Recommender.java │ │ │ └── resources │ │ │ └── log4j.properties │ └── python │ │ ├── .gitignore │ │ ├── README.asciidoc │ │ ├── app.py │ │ ├── killrvideo_dsl │ │ ├── __init__.py │ │ ├── dsl.py │ │ ├── genre.py │ │ └── kv.py │ │ └── setup.py ├── killrvideo-mapping.groovy ├── killrvideo-mapping.groovy.config ├── schema.groovy └── verify.csv ├── london-tube ├── README.md ├── Schema.png ├── london-tube-map.pdf ├── london_edges.csv ├── london_tube.gryo ├── london_tube_mapping.groovy ├── london_vertices.csv └── schema.groovy ├── northwind ├── Northwind_Schema.png ├── README.md ├── code │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── datastax │ │ └── examples │ │ └── northwind │ │ └── Northwind.java ├── data │ ├── facebook_members.csv │ ├── identity_c2fb.csv │ ├── isFriendsWith.csv │ ├── isRelatedTo.csv │ ├── northwind.kryo │ └── rated.csv ├── datamodel-screenshot.png ├── northwind-mapping.groovy ├── northwind-mapping.groovy.config ├── schema.groovy ├── supplemental-data-mapping.groovy ├── supplemental-data-mapping.groovy.config └── verify.csv ├── paging-graph-results ├── .gitignore ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── datastax │ └── graphpractice │ └── example │ └── App.java ├── pokemon ├── README.md ├── data │ ├── edges │ │ ├── category_has_pocket_type.csv │ │ ├── item_has_category.csv │ │ ├── location_belongs_to_region.csv │ │ ├── pokemon_can_use_item.csv │ │ ├── pokemon_evolves_to.csv │ │ ├── pokemon_has_abilities.csv │ │ ├── pokemon_has_egg_groups.csv │ │ ├── pokemon_has_location_index.csv │ │ ├── pokemon_has_moves.csv │ │ ├── pokemon_has_stats.csv │ │ └── pokemon_has_type.csv │ └── vertices │ │ ├── abilities.csv │ │ ├── egg_groups.csv │ │ ├── genders.csv │ │ ├── item_categories.csv │ │ ├── item_pockets.csv │ │ ├── items.csv │ │ ├── locations.csv │ │ ├── moves.csv │ │ ├── pokemon.csv │ │ ├── regions.csv │ │ ├── stats.csv │ │ └── types.csv ├── graphloader_command.txt ├── poke_mapper.groovy ├── poke_mapper.groovy.config ├── schema.groovy └── verify.csv ├── startup └── traversal-builder ├── README.md ├── bin ├── run.sh └── traversal-builder.jar ├── pom.xml └── src └── main ├── java └── com │ └── datastax │ └── examples │ └── builder │ ├── App.java │ ├── AppState.java │ ├── Commands.java │ ├── ShortestPathTraversals.java │ └── shortestPath │ └── ShortestPathQueryBuilder.java └── resources ├── graph.groovy ├── graph.txt └── schema.groovy /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ 2 | .idea/ 3 | *.iml 4 | *.ipr 5 | *.iws 6 | 7 | # Eclipse 8 | .classpath 9 | .project 10 | .metadata 11 | .settings/ 12 | local.properties 13 | 14 | # Maven, etc. 15 | out/ 16 | target/ 17 | 18 | # General 19 | *~ 20 | *.bak 21 | *.sw[o,p] 22 | *.tmp 23 | .DS_Store 24 | Thumbs.db -------------------------------------------------------------------------------- /.startup/fraud: -------------------------------------------------------------------------------- 1 | export ROOTDIR=/tmp 2 | 3 | echo "Creating the fraud schema" 4 | dse gremlin-console -e fraud/schema.groovy 5 | 6 | echo "Loading fraud data" 7 | $ROOTDIR/dse-graph-loader*/graphloader -graph fraud -address `hostname --ip-address` fraud/fraud-mapping.groovy -inputpath fraud/data 8 | 9 | echo "Configuring Studio" 10 | 11 | set -x 12 | 13 | IP=$(ifconfig | awk '/inet/ { print $2 }' | egrep -v '^fe|^127|^192|^172|::' | head -1) 14 | IP=${IP#addr:} 15 | 16 | DL_SUFFIX=Linux-64bit 17 | INNER_SUFFIX=linux_amd64 18 | HUGO_VERSION=0.27 19 | 20 | if [[ $HOSTNAME == "node"* ]] ; then 21 | #rightscale 22 | IP=$(grep $(hostname)_ext /etc/hosts | awk '{print $1}') 23 | export WORK_DIR=/tmp 24 | fi 25 | 26 | if [[ "$OSTYPE" == "darwin"* ]]; then 27 | # Mac OSX 28 | IP=localhost 29 | DL_SUFFIX=macOS-64bit 30 | INNER_SUFFIX=macos-64bit 31 | fi 32 | 33 | echo "Importing Notebooks...." 34 | 35 | curl -H "Accept-Encoding: gzip" -X POST -F 'file=@./fraud/studio/4_of_4_Fraud_Scenarios.studio-nb.tar' http://$IP:9091/api/v1/notebooks/import &> /dev/null 36 | curl -H "Accept-Encoding: gzip" -X POST -F 'file=@./fraud/studio/3_of_4_Indexing_and_Traversing_Graph_Data.studio-nb.tar' http://$IP:9091/api/v1/notebooks/import &> /dev/null 37 | curl -H "Accept-Encoding: gzip" -X POST -F 'file=@./fraud/studio/2_of_4_Populating_and_Traversing_the_Graph.studio-nb.tar' http://$IP:9091/api/v1/notebooks/import &> /dev/null 38 | curl -H "Accept-Encoding: gzip" -X POST -F 'file=@./fraud/studio/1_of_4_Creating_DSE_Graph_and_Graph_Schema.studio-nb.tar' http://$IP:9091/api/v1/notebooks/import &> /dev/null 39 | 40 | echo "Updating default connection to node0" 41 | 42 | export CONNECTION_DIRECTORY=/root/.datastax_studio/connections/admin 43 | export DEFAULT_CONNECTION_NAME="default cluster" 44 | export DEFAULT_CONNECTION_HOST=node0 45 | 46 | sed -i -e "s/default localhost/$DEFAULT_CONNECTION_NAME/g" $CONNECTION_DIRECTORY/418ed742-cd61-4df8-abd8-07bc56a62e8d 47 | sed -i -e "s/127.0.0.1/$DEFAULT_CONNECTION_HOST/g" $CONNECTION_DIRECTORY/418ed742-cd61-4df8-abd8-07bc56a62e8d -------------------------------------------------------------------------------- /.startup/northwind: -------------------------------------------------------------------------------- 1 | dse gremlin-console -e northwind/schema.groovy 2 | /tmp/dse-graph-loader*/graphloader -graph northwind -address `hostname --ip-address` northwind/northwind-mapping.groovy -inputpath northwind/data -------------------------------------------------------------------------------- /.startup/startup.order: -------------------------------------------------------------------------------- 1 | northwind 2 | fraud -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/author.csv: -------------------------------------------------------------------------------- 1 | name|gender 2 | Julia Child|F 3 | Simone Beck|F 4 | Louisette Bertholie|F 5 | Patricia Simon|F 6 | Alice Waters|F 7 | Patricia Curtan|F 8 | Kelsie Kerr|F 9 | Fritz Streiff|M 10 | Emeril Lagasse|M 11 | James Beard|M 12 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/authorBook.csv: -------------------------------------------------------------------------------- 1 | bname|aname 2 | The Art of French Cooking, Vol. 1|Julia Child 3 | The Art of French Cooking, Vol. 1|Simone Beck 4 | The Art of French Cooking, Vol. 1|Louisette Bertholie 5 | Simca's Cuisine: 100 Classic French Recipes for Every Occasion|Simone Beck 6 | Simca's Cuisine: 100 Classic French Recipes for Every Occasion|Patricia Simon 7 | The French Chef Cookbook|Julia Child 8 | The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution|Alice Waters 9 | The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution|Patricia Curtan 10 | The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution|Kelsie Kerr 11 | The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution|Fritz Streiff 12 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/authorBookMappingCSV.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | author: Julia Child|F 3 | book : Simca's Cuisine: 100 Classic French Recipes for Every Occasion|1972|0-394-40152-2 4 | authorBook: Simca's Cuisine: 100 Classic French Recipes for Every Occasion|Simone Beck 5 | */ 6 | 7 | // CONFIGURATION 8 | // Configures the data loader to create the schema 9 | config dryrun: false, preparation: true, create_schema: true, load_new: true, load_vertex_threads: 3, schema_output: 'loader_output.txt' 10 | 11 | // DATA INPUT 12 | // Define the data input source (a file which can be specified via command line arguments) 13 | // inputfiledir is the directory for the input files 14 | inputfiledir = '/graph-examples/documentation-examples/CSV/authorBook/' 15 | authorInput = File.csv(inputfiledir + "author.csv").delimiter('|') 16 | bookInput = File.csv(inputfiledir + "book.csv").delimiter('|') 17 | authorBookInput = File.csv(inputfiledir + "authorBook.csv").delimiter('|') 18 | 19 | //Specifies what data source to load using which mapper (as defined inline) 20 | 21 | load(authorInput).asVertices { 22 | label "author" 23 | key "name" 24 | } 25 | 26 | load(bookInput).asVertices { 27 | label "book" 28 | key "name" 29 | } 30 | 31 | load(authorBookInput).asEdges { 32 | label "authored" 33 | outV "aname", { 34 | label "author" 35 | key "name" 36 | } 37 | inV "bname", { 38 | label "book" 39 | key "name" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/book.csv: -------------------------------------------------------------------------------- 1 | name|year|ISBN 2 | The Art of French Cooking, Vol. 1|1961|none 3 | Simca's Cuisine: 100 Classic French Recipes for Every Occasion|1972|0-394-40152-2 4 | The French Chef Cookbook|1968|0-394-40135-2 5 | The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution|2007|0-307-33679-4 6 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/readme.md: -------------------------------------------------------------------------------- 1 | ## Simple CSV example using authors and books 2 | * [Mapping script] (authorBookMappingCSV.groovy) 3 | * [schema] (schema.groovy) 4 | * [graphloader script] (runDGL.sh) 5 | * [author.csv] (author.csv) 6 | * [book.csv] (book.csv) 7 | * [authorBook.csv - edges] (authorBook.csv) 8 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/$VERSION/graphloader 14 | TYPE=CSV 15 | INPUTEXAMPLE='authorBook' 16 | INPUTBASEDIR='/graph-examples/documentation-examples' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='authorBookMapping'$TYPE'.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/CSV/authorBook/schema.groovy: -------------------------------------------------------------------------------- 1 | // SCHEMA 2 | // PROPERTIES 3 | schema.propertyKey('name').Text().ifNotExists().create() 4 | schema.propertyKey('gender').Text().create() 5 | schema.propertyKey('year').Int().create() 6 | schema.propertyKey('ISBN').Text().create() 7 | // VERTEX LABELS 8 | schema.vertexLabel('author').properties('name','gender','nickname').ifNotExists().create() 9 | schema.vertexLabel('book').properties('name','year').create() 10 | // EDGE LABELS 11 | schema.edgeLabel('authored').connection('author','book').ifNotExists().create() 12 | // INDEXES 13 | schema.vertexLabel('author').index('byName').secondary().by('name').add() 14 | schema.vertexLabel('book').index('search').search().by('name').asString().by('year').add() 15 | 16 | -------------------------------------------------------------------------------- /documentation-examples/CSV/edgeProperty/edgePropertyMapping.groovy: -------------------------------------------------------------------------------- 1 | // MAPPING SCRIPT 2 | 3 | /* SAMPLE INPUT 4 | person: Julia 5 | personKnowsEdge: Julia|James Beard|knew each other in New York 6 | */ 7 | 8 | // CONFIGURATION 9 | // Configures the data loader to create the schema 10 | config dryrun: false, preparation: true, create_schema: true, load_new: true, load_vertex_threads: 3, schema_output: 'loader_output.txt' 11 | 12 | // DATA INPUT 13 | // Define the data input source (a file which can be specified via command line arguments) 14 | // inputfiledir is the directory for the input files 15 | inputfiledir = '/Users/lorinapoland/CLONES/graph-examples/food/CSV/edgeProperty/' 16 | personInput = File.csv(inputfiledir + "person.csv").delimiter('|') 17 | personKnowsEdgesInput = File.csv(inputfiledir + "personKnowsEdges.csv").delimiter('|') 18 | 19 | //Specifies what data source to load using which mapper (as defined inline) 20 | 21 | load(personInput).asVertices { 22 | label "person" 23 | key "name" 24 | } 25 | 26 | load(personKnowsEdgesInput).asEdges { 27 | label "knows" 28 | outV "aname", { 29 | label "person" 30 | key "name" 31 | } 32 | inV "bname", { 33 | label "person" 34 | key "name" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /documentation-examples/CSV/edgeProperty/person.csv: -------------------------------------------------------------------------------- 1 | name 2 | Lori 3 | Pam 4 | Paul 5 | Barrie 6 | Terri 7 | Jim 8 | Ian 9 | -------------------------------------------------------------------------------- /documentation-examples/CSV/edgeProperty/personKnowsEdges.csv: -------------------------------------------------------------------------------- 1 | aname|bname|notes 2 | Lori|Pam|work and personal 3 | Lori|Paul|work 4 | Lori|Jim|work and personal 5 | -------------------------------------------------------------------------------- /documentation-examples/CSV/edgeProperty/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/Users/lorinapoland/CLONES/$VERSION/graphloader 14 | TYPE=CSV 15 | INPUTEXAMPLE='edgeProperty' 16 | INPUTBASEDIR='/Users/lorinapoland/CLONES/graph-examples/food' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='edgePropertyMapping.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/CSV/edgeProperty/schema.groovy: -------------------------------------------------------------------------------- 1 | // SCHEMA 2 | schema.propertyKey('name').Text().single().ifNotExists().create() 3 | schema.propertyKey('notes').Text().multiple().ifNotExists().create() 4 | schema.vertexLabel('person').ifNotExists().create() 5 | schema.edgeLabel('knows').multiple().properties('notes').ifNotExists().create() 6 | schema.edgeLabel('knows').connection('person', 'person').add() 7 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/fridgeItem.csv: -------------------------------------------------------------------------------- 1 | city_id|sensor_id|fridgeItem 2 | santaCruz|93c4ec9b-68ff-455e-8668-1056ebc3689f|asparagus 3 | sacramento|9c23b683-1de2-4c97-a26a-277b3733732a|ham 4 | sacramento|eff4a8af-2b0d-4ba9-a063-c170130e2d84|eggs 5 | santaCruz|b6c20c89-06d5-4f3c-9424-030c35a00dff|beef 6 | davis|ad7a68bc-31b4-4a2d-a109-9867eae3cce3|beef 7 | davis|9c23b683-1de2-4c97-a26a-277b3733732a|chicken 8 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/fridgeItemEdges.csv: -------------------------------------------------------------------------------- 1 | city_id|sensor_id|name 2 | santaCruz|93c4ec9b-68ff-455e-8668-1056ebc3689f|asparagus 3 | sacramento|9c23b683-1de2-4c97-a26a-277b3733732a|ham 4 | sacramento|eff4a8af-2b0d-4ba9-a063-c170130e2d84|eggs 5 | santaCruz|b6c20c89-06d5-4f3c-9424-030c35a00dff|beef 6 | davis|ad7a68bc-31b4-4a2d-a109-9867eae3cce3|beef 7 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/fridgeItemMappingCOMPKEY.groovy: -------------------------------------------------------------------------------- 1 | // Composite key example 2 | // Run schema.groovy first to create the schema 3 | // graphloader does not currently create the schema correctly for 4 | // composite keys, esp. for edge loading 5 | // Run runDGL.sh to load data 6 | 7 | /* SAMPLE INPUT 8 | city_id|sensor_id|fridgeItem 9 | santaCruz|93c4ec9b-68ff-455e-8668-1056ebc3689f|asparagus 10 | */ 11 | 12 | // CONFIGURATION 13 | // Configures the data loader to create the schema 14 | //config create_schema: false, load_new: true 15 | config load_new: true, dryrun: false, preparation: true, create_schema: true, schema_output: '/tmp/loader_output.txt' 16 | 17 | // DATA INPUT 18 | // Define the data input source (a file which can be specified via command line arguments) 19 | // inputfiledir is the directory for the input files that is given in the commandline 20 | // as the "-filename" option 21 | inputfiledir = '/graph-examples/documentation-examples/CSV/fridgeItem_COMPKEY/' 22 | fridgeItemInput = File.csv(inputfiledir + "fridgeItem.csv").delimiter('|') 23 | ingredInput = File.csv(inputfiledir + "ingredients.csv").delimiter('|') 24 | the_edges = File.csv(inputfiledir + "fridgeItemEdges.csv").delimiter('|') 25 | 26 | the_edges = the_edges.transform { 27 | it['FridgeSensor'] = [ 28 | 'city_id' : it['city_id'], 29 | 'sensor_id' : it['sensor_id'] ]; 30 | it['ingredient'] = [ 31 | 'name' : it['name'] ]; 32 | it 33 | } 34 | 35 | //Specifies what data source to load using which mapper (as defined inline) 36 | 37 | load(ingredInput).asVertices { 38 | label "ingredient" 39 | key "name" 40 | } 41 | 42 | load(fridgeItemInput).asVertices { 43 | label "FridgeSensor" 44 | key city_id: "city_id", sensor_id: "sensor_id" 45 | } 46 | 47 | load(the_edges).asEdges { 48 | label "linked" 49 | outV "ingredient", { 50 | label "ingredient" 51 | key "name" 52 | } 53 | inV "FridgeSensor", { 54 | label "FridgeSensor" 55 | key city_id:"city_id", sensor_id:"sensor_id" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/ingredients.csv: -------------------------------------------------------------------------------- 1 | name 2 | beef 3 | onion 4 | mashed garlic 5 | butter 6 | tomato paste 7 | eggplant 8 | zucchini 9 | olive oil 10 | yellow onion 11 | green beans 12 | tuna 13 | tomato 14 | hard-boiled egg 15 | egg noodles 16 | mushrooms 17 | bacon 18 | celery 19 | green bell pepper 20 | ground beef 21 | pork sausage 22 | shallots 23 | chervil 24 | fennel 25 | parsley 26 | oyster 27 | Pernod 28 | thyme 29 | carrots 30 | chicken broth 31 | pork loin 32 | red wine 33 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/readme.md: -------------------------------------------------------------------------------- 1 | # CSV Examples 2 | ## Composite key example 3 | * [Mapping script] (fridgeItemMappingCOMPKEY.groovy) 4 | * [schema] (schema.groovy) 5 | * [graphloader script] (runDGL.sh) 6 | * [fridgeItem.csv] (fridgeItem.csv) 7 | * [ingredients.csv] (ingredients.csv) 8 | * [fridgeItemEdges.csv - edges] (fridgeItemEdges.csv) 9 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/$VERSION/graphloader 14 | TYPE=CSV 15 | INPUTEXAMPLE='fridgeItem_COMPKEY' 16 | INPUTBASEDIR='/graph-examples/documentation-examples' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='fridgeItemMappingCOMPKEY.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/CSV/fridgeItemCOMPKEY/schema.groovy: -------------------------------------------------------------------------------- 1 | // SCHEMA 2 | // Example of custom vertex id: 3 | // PROPERTIES 4 | schema.propertyKey('fridgeItem').Text().create() 5 | schema.propertyKey('city_id').Text().create() 6 | schema.propertyKey('sensor_id').Uuid().create() 7 | schema.propertyKey('location').Point().create() 8 | // VERTEX LABELS 9 | schema.vertexLabel('ingredient').create() 10 | schema.vertexLabel('FridgeSensor').partitionKey('city_id').clusteringKey('sensor_id').create() 11 | schema.vertexLabel('FridgeSensor').properties('fridgeItem', 'location').add() 12 | // EDGE LABELS 13 | schema.edgeLabel('isIn').connection('ingredient','FridgeSensor').create() 14 | -------------------------------------------------------------------------------- /documentation-examples/CSV/gzip_test/gzipMapping.groovy: -------------------------------------------------------------------------------- 1 | // CONFIGURATION 2 | // Configures the data loader to create the schema 3 | config dryrun: false, preparation: true, create_schema: true, load_new: true, load_vertex_threads: 3, schema_output: 'loader_output.txt' 4 | 5 | // DATA INPUT 6 | // Define the data input source (a file which can be specified via command line arguments) 7 | // inputfiledir is the directory for the input files 8 | inputfiledir = '/graph-examples/documentation-examples/CSV/gzip_test/' 9 | recipeInput = File.csv(inputfiledir +"recipes.csv.gz").gzip().delimiter('|') 10 | 11 | //Specifies what data source to load using which mapper (as defined inline) 12 | 13 | load(recipeInput).asVertices { 14 | label "recipe" 15 | key "name" 16 | isNew() 17 | } 18 | -------------------------------------------------------------------------------- /documentation-examples/CSV/gzip_test/readme.md: -------------------------------------------------------------------------------- 1 | # CSV Examples 2 | ## Gzip example 3 | * [Mapping script] (gzipMapping.groovy) 4 | * [graphloader script] (runDGL.sh) 5 | * [recipes.csv.gz] (gzip file) 6 | -------------------------------------------------------------------------------- /documentation-examples/CSV/gzip_test/recipes.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/documentation-examples/CSV/gzip_test/recipes.csv.gz -------------------------------------------------------------------------------- /documentation-examples/CSV/gzip_test/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/$VERSION/graphloader 14 | TYPE=CSV 15 | INPUTEXAMPLE='gzip_test' 16 | INPUTBASEDIR='/graph-examples/documentation-examples/' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='gzipMapping.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/CSV/meals.csv: -------------------------------------------------------------------------------- 1 | SaturdayFeast::2015-11-30T00:00:00.00Z::1,000::Beef Bourguignon|Carrot Soup|Oysters Rockefeller 2 | EverydayDinner::2016-01-14T00:00:00.00Z::600::Roast Pork Loin|Carrot Soup 3 | JuliaDinner::2016-01-14T00:00:00.00Z::900::Beef Bourguignon|Salade Nicoise 4 | -------------------------------------------------------------------------------- /documentation-examples/CSV/readme.md: -------------------------------------------------------------------------------- 1 | # CSV Examples 2 | * [Simple CSV example using authors and books] (authorBook/readme.md) 3 | * [Composite key example] (fridgeItemCOMPKEY/readme.md) 4 | * [Gzip example] (gzip_test/readme.md) 5 | * [Reviewer-Rating example] (reviewerRating/readme.md) 6 | -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/readme.md: -------------------------------------------------------------------------------- 1 | # CSV Examples 2 | ## Reviewer-Rating example 3 | * [Mapping script] (reviewerRatingMapping.groovy) 4 | * [graphloader script] (runDGL.sh) 5 | * [schema] (schema.groovy) 6 | * [reviewers.csv.gz] (reviewers.csv gzip file) 7 | * [recipes.csv.gz] (recipes.csv gzip file) 8 | * [reviewerRatings.csv.gz - edges] (reviewerRatings.csv gzip file) 9 | * [recipes_complete.csv] (recipes_complete.csv) 10 | -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/recipes.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/documentation-examples/CSV/reviewerRating/recipes.csv.gz -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/recipes_complete.csv: -------------------------------------------------------------------------------- 1 | name|author_name|instruction 2 | Beef Bourguignon|Julia Child|(beef,2 lbs)|(onions,1 sliced)|(mashed garlic,2 cloves)|(butter, 3.5 Tbsp)|(tomato paste,1Tbsp)|Braise the beef. Saute the onions and carrots. Add wine and cook in a dutch oven at 425 degrees for 1 hour. 3 | Ratatouille|Julia Child|(eggplant,1 lb)|(zucchini,1 lb)|(mashed garlic,2 cloves)|(olive oil,4-6 Tbsp)|(yellow onion, 1 1/2 cups or 1/2 lb thinly sliced)|Peel and cut the egglant. Make sure you cut eggplant into lengthwise slices that are about 1-inch wide, 3-inches long, and 3/8-inch thick. 4 | Salade Nicoise|Julia Child|(olive oil,2-3 Tbsp)|(green beans,1 1/2 lbs blanched, trimmed)|(tuna,8-10 ozs oil-packed, drained and flaked)|(tomatoes, 3 or 4 red, peeled, quartered, cored, and seasoned)|(hard-boiled eggs,8 halved lengthwise)|Take a salad bowl or platter and line it with lettuce leaves, shortly before serving. Drizzle some olive oil on the leaves and dust them with salt. 5 | Wild Mushroom Stroganoff|Emeril Lagasse|(egg noodles,16 ozs wide)|(olive oil,3 Tbsp)|(mushrooms,2 lbs wild or exotic, cleaned, stemmed, and sliced)|(yellow onion,1 cup thinly sliced)|Cook the egg noodles according to the package directions and keep warm. Heat 1 1/2 tablespoons of the oliveoil in a large saute pan over medium-high heat. 6 | Spicy Meatloaf|Emeril Lagasse::(bacon,3 ozs diced)|(onion,2 cups finely chopped)|(celery,2 cups finely chopped)|(green bell pepper,1/4 cup finely chopped)|(ground beef,1 1/2 lbs chuck)|(pork sausage,3/4 lbs hot)::Preheat the oven to 375 degrees F. Cook bacon in a large skillet over medium heat until very crisp and fat has rendered, 8-10 minutes. 7 | Oysters Rockefeller::James Beard::(shallots,1/4 cup chopped)|(celery,1/4 cup chopped)|(chervil,1 tsp)|(fennel,1/3 cup chopped)|(parsley,1/3 cup chopped)|(oysters, 2 dozen on the half shell)|(Pernod,1/3 cup)::Saute the shallots, celery, herbs, and seasonings in 3 tablespoons of the butter for 3 minutes. Add the watercress and let it wilt. 8 | Carrot Soup::Alice Waters::(butter,4 Tbsp)|(onions,2 medium sliced)|(thyme,1 sprig)|(carrots,2 1/2 lbs, peeled and sliced)|(chicken broth,6 cups)::In a heavy-bottomed pot, melt the butter. When it starts to foam, add the onions and thyme and cook over medium-low heat until tender, about 10 minutes. 9 | Roast Pork Loin::Alice Waters::(pork loin,1 bone-in, 4-rib)|(red wine,1/2 cup)|(chicken broth,1 cup)|The day before, separate the meat from the ribs, stopping about 1 inch before the end of the bones. Season the pork liberally inside and out with salt and pepper and refrigerate overnight. 10 | -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/reviewerRatingMapping.groovy: -------------------------------------------------------------------------------- 1 | // Input reviewers and ratings and link to recipes 2 | // Run runDGL.sh 3 | 4 | /* SAMPLE INPUT 5 | reviewer: John Doe 6 | recipe: Beef Bourguignon 7 | reviewerRating :John Doe|Beef Bourguignon|2014-01-01|5|comment 8 | */ 9 | 10 | // CONFIGURATION 11 | // Configures the data loader to create the schema 12 | config preparation: true, create_schema: true, load_new: false 13 | 14 | // DATA INPUT 15 | // Define the data input source (a file which can be specified via command line arguments) 16 | // inputfiledir is the directory for the input files that is given in the commandline 17 | // as the "-filename" option 18 | inputfiledir = '/graph-examples/documentation-examples/CSV/reviewerRating/' 19 | // This next file is not required if the reviewers already exist 20 | reviewerInput = File.csv(inputfiledir + "reviewers.csv.gz").gzip().delimiter('|') 21 | // This next file is not required if the recipes already exist 22 | recipeInput = File.csv(inputfiledir +"recipes.csv.gz").gzip().delimiter('|') 23 | // This is the file that is used to create the edges with edge properties 24 | reviewerRatingInput = File.csv(inputfiledir + "reviewerRatings.csv.gz").gzip().delimiter('|') 25 | 26 | //Specifies what data source to load using which mapper (as defined inline) 27 | 28 | load(reviewerInput).asVertices { 29 | label "reviewer" 30 | key "name" 31 | } 32 | 33 | load(recipeInput).asVertices { 34 | label "recipe" 35 | key "name" 36 | } 37 | 38 | load(reviewerRatingInput).asEdges { 39 | label "rated" 40 | outV "rev_name", { 41 | label "reviewer" 42 | key "name" 43 | } 44 | inV "recipe_name", { 45 | label "recipe" 46 | key "name" 47 | } 48 | // properties are automatically added from the file, using the header line as property keys 49 | } 50 | -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/reviewerRatings.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/documentation-examples/CSV/reviewerRating/reviewerRatings.csv.gz -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/reviewers.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/documentation-examples/CSV/reviewerRating/reviewers.csv.gz -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/$VERSION/graphloader 14 | TYPE=CSV 15 | INPUTEXAMPLE='reviewerRating' 16 | INPUTBASEDIR='/graph-examples/documentation-examples' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='reviewerRatingMapping.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/CSV/reviewerRating/schema.groovy: -------------------------------------------------------------------------------- 1 | // SCHEMA 2 | // PROPERTIES 3 | schema.propertyKey('name').Text().single().create() 4 | schema.propertyKey('comment').Text().single().create() 5 | schema.propertyKey('stars').Int().single().create() 6 | schema.propertyKey('timestamp').Timestamp().single().create() 7 | // VERTEX LABELS 8 | schema.vertexLabel('recipe').properties('name').create() 9 | schema.vertexLabel('reviewer').properties('name').create() 10 | // EDGE LABELS 11 | schema.edgeLabel('rated').properties('comment', 'timestamp', 'stars').connection('reviewer', 'recipe').create() 12 | // INDEXES 13 | schema.vertexLabel('reviewer').index('byname').materialized().by('name').add() 14 | schema.vertexLabel('recipe').index('byname').materialized().by('name').add() 15 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/data/geodetic.csv: -------------------------------------------------------------------------------- 1 | name|point 2 | Paris|POINT(2.352222, 48.856614) 3 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/geodetic-data.groovy: -------------------------------------------------------------------------------- 1 | // Geodetic example - NO SEARCH INDEX 2 | 3 | :remote config alias g geodetic51.g 4 | schema.config().option('graph.allow_scan').set('true') 5 | 6 | // Create points 7 | graph.addVertex(label,'location','name','Paris','point',Geo.point(2.352222, 48.856614)) 8 | graph.addVertex(label,'location','name','London','point',Geo.point(-0.127758,51.507351)) 9 | graph.addVertex(label,'location','name','Dublin','point',Geo.point(-6.26031, 53.349805)) 10 | graph.addVertex(label,'location','name','Aachen','point',Geo.point(6.083887, 50.775346)) 11 | graph.addVertex(label,'location','name','Tokyo','point',Geo.point(139.691706, 35.689487)) 12 | 13 | // Create linestrings 14 | graph.addVertex(label, 'lineLocation', 'name', 'ParisLondon', 'line', "LINESTRING(2.352222 48.856614, -0.127758 51.507351)") 15 | graph.addVertex(label, 'lineLocation', 'name', 'LondonDublin', 'line', "LINESTRING(-0.127758 51.507351, -6.26031 53.349805)") 16 | graph.addVertex(label, 'lineLocation', 'name', 'ParisAachen', 'line', "LINESTRING(2.352222 48.856614, 6.083887 50.775346)") 17 | graph.addVertex(label, 'lineLocation', 'name', 'AachenTokyo', 'line', "LINESTRING(6.083887 50.775346, 139.691706 35.689487)") 18 | 19 | // Create polygons 20 | graph.addVertex(label, 'polyLocation','name', 'ParisLondonDublin', 'polygon',Geo.polygon(2.352222, 48.856614, -0.127758, 51.507351, -6.26031, 53.349805)) 21 | graph.addVertex(label, 'polyLocation','name', 'LondonDublinAachen', 'polygon',Geo.polygon(-0.127758, 51.507351, -6.26031, 53.349805, 6.083887, 50.775346)) 22 | graph.addVertex(label, 'polyLocation','name', 'DublinAachenTokyo', 'polygon',Geo.polygon(-6.26031, 53.349805, 6.083887, 50.775346, 139.691706, 35.689487)) 23 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/geodetic-map-script.groovy: -------------------------------------------------------------------------------- 1 | config create_schema: false, load_new: true 2 | 3 | import com.datastax.driver.dse.geometry.Point 4 | 5 | locationsFile = File.csv(inputfilename).delimiter('|') 6 | 7 | locationsFile = locationsFile.transform { 8 | it['point'] = Point.fromWellKnownText(it['point']); 9 | return it; 10 | } 11 | 12 | load(locationsFile).asVertices { 13 | label "location" 14 | key "name" 15 | } 16 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/geodetic-queries.groovy: -------------------------------------------------------------------------------- 1 | // Geodetic example - NO SEARCH INDEX 2 | 3 | :remote config alias g geodetic51.g 4 | //schema.config().option('graph.allow_scan').set('true') 5 | schema.config().option('graph.allow_scan').set('false') 6 | 7 | // DISTANCES 8 | // PARIS TO LONDON: 3.7 DEGREES; 3.629973 CART; 344 KM; 214 MI; 344,000 M 9 | // PARIS TO AACHEN: 4.2 DEGREES; 4.196052 CART; 343 KM; 213 MI; 343,000 M 10 | // PARIS TO DUBLIN: 9.8 DEGREES; 9.714138 CART; 781 KM; 485 MI; 781,000 M 11 | // PARIS TO TOYKO: 138 DEGREES; 137.969225 CART; 9713 KM; 6035 MI; 9,713,000 M 12 | 13 | // Test point 14 | g.V().hasLabel('location').valueMap() 15 | // Test that no points are inside distance from (0,0) to 1 degree of radius 16 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 1, Geo.Unit.DEGREES)).values('name') 17 | // Test that Paris and London are inside distance from Paris to London 18 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 3.7, Geo.Unit.DEGREES)).values('name') 19 | // Test that Paris, London, and Aachen are inside distance from Paris to Aachen 20 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 4.2, Geo.Unit.DEGREES)).values('name') 21 | // Test that Paris, London, Aachen, and Dublin are inside distance from Paris to Dublin 22 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 9.8, Geo.Unit.DEGREES)).values('name') 23 | // Test that all location are inside distance from Paris to Tokyo 24 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 138, Geo.Unit.DEGREES)).values('name') 25 | // Test that Paris is inside distance of 300 km centered on Paris 26 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 300, Geo.Unit.KILOMETERS)).values('name') 27 | // Test that Paris and Aachen are inside distance of 341 km centered on Paris 28 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 341, Geo.Unit.KILOMETERS)).values('name') 29 | // Test that Paris is inside distance of 1 mile centered on Paris 30 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 1, Geo.Unit.MILES)).values('name') 31 | // Test that Paris and Aachen are inside distance of 212 mile centered on Paris 32 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 212, Geo.Unit.MILES)).values('name') 33 | // Test that Paris is inside distance of 10 meters centered on Paris 34 | g.V().has('location', 'point', Geo.inside(Geo.point(2.352222, 48.856614), 10, Geo.Unit.METERS)).values('name') 35 | 36 | // Test linestring 37 | g.V().hasLabel('lineLocation').valueMap() 38 | // Test that no linestrings are inside distance from Paris to 1 degree of radius 39 | g.V().has('lineLocation', 'line', Geo.inside(Geo.point(2.352222, 48.856614), 1, Geo.Unit.DEGREES)).values('name') 40 | // Test that line between Paris and London are inside distance from Paris to London 41 | g.V().has('lineLocation', 'line', Geo.inside(Geo.point(2.352222, 48.856614), 3.7, Geo.Unit.DEGREES)).values('name') 42 | // Test that lines between Paris and London and Paris and Aachen are inside distance from Paris to Aachen 43 | g.V().has('lineLocation', 'line', Geo.inside(Geo.point(2.352222, 48.856614), 4.2, Geo.Unit.DEGREES)).values('name') 44 | // Test that all lines are inside distance from Paris to Dublin 45 | g.V().has('lineLocation', 'line', Geo.inside(Geo.point(2.352222, 48.856614), 9.8, Geo.Unit.DEGREES)).values('name') 46 | 47 | // Test polygon 48 | g.V().hasLabel('polyLocation').valueMap() 49 | // Test that no polygons are inside distance from Paris to 1 degree of radius 50 | g.V().has('polyLocation', 'polygon', Geo.inside(Geo.point(2.352222, 48.856614), 1, Geo.Unit.DEGREES)).values('name') 51 | // Test that ParisLondonDublin and LondonDublinAachen polygons are inside distance from Paris to Dublin 52 | g.V().has('polyLocation', 'polygon', Geo.inside(Geo.point(2.352222, 48.856614), 9.8, Geo.Unit.DEGREES)).values('name') 53 | // Test that all polygons are inside distance from Paris to Toyko 54 | g.V().has('polyLocation', 'polygon', Geo.inside(Geo.point(2.352222, 48.856614), 138, Geo.Unit.DEGREES)).values('name') 55 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/geodetic-schema.groovy: -------------------------------------------------------------------------------- 1 | // Geodetic example - NO SEARCH INDEX 2 | 3 | system.graph('geodetic51').ifNotExists().create() 4 | :remote config alias g geodetic51.g 5 | schema.config().option('graph.allow_scan').set('true') 6 | 7 | // Schema 8 | // Note use of withGeoBounds() 9 | schema.propertyKey('name').Text().create() 10 | schema.propertyKey('point').Point().withGeoBounds().create() 11 | schema.vertexLabel('location').properties('name','point').create() 12 | schema.propertyKey('line').Linestring().withGeoBounds().create() 13 | schema.vertexLabel('lineLocation').properties('name','line').create() 14 | schema.propertyKey('polygon').Polygon().withGeoBounds().create() 15 | schema.vertexLabel('polyLocation').properties('name','polygon').create() 16 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/graphloader_command.txt: -------------------------------------------------------------------------------- 1 | # change paths 2 | /path/to/graphloader /path/to/geodetic-map-script.groovy -graph testGeo51 -address localhost -abort_on_prep_errors false -inputpath /path/to/directory/containing/data 3 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/readme.md: -------------------------------------------------------------------------------- 1 | ## Geospatial examples 2 | * [geodetic schema to test without search index] (geodetic-schema.groovy) 3 | * [geodetic data - as graph.addVertex] (geodetic-data.groovy) 4 | * [geodetic queries] (geodetic-queries.groovy) 5 | * [geodetic-map-script.groovy] (geodetic-map-script.groovy) 6 | * [data/geodetic.csv - as CSV data for use with graphloader] (data/geodetic.csv) 7 | * [graphloader_command.txt] (graphloader_command.txt) 8 | * [verify.groovy - file to verify queries] (verify.groovy) 9 | 10 | Geodetic data is not currently supported by DSE Graphloader, so a groovy script is used to load the data. 11 | (DSE Graphloader support being added, experimental until merged.) 12 | 13 | -------------------------------------------------------------------------------- /documentation-examples/GEO/5.1/verify.groovy: -------------------------------------------------------------------------------- 1 | g.V().count()|1 2 | -------------------------------------------------------------------------------- /documentation-examples/JSON/authorBookMap_JSON.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | author: {"author_name":"Julia Child","gender":"F"} 3 | book : {"name":"The Art of French Cooking, Vol. 1","year":"1961","ISBN":"none"} 4 | authorBook: {"name":"The Art of French Cooking, Vol. 1","author":"Julia Child"} 5 | */ 6 | 7 | // CONFIGURATION 8 | // Configures the data loader to create the schema 9 | config create_schema: false, load_new: true, load_vertex_threads: 3 10 | 11 | // DATA INPUT 12 | if (inputpath == '') { 13 | inputfileV = new java.io.File('.').getCanonicalPath() + '/data/vertices/' 14 | inputfileE = new java.io.File('.').getCanonicalPath() + '/data/edges/' 15 | } 16 | else { 17 | inputfileV = inputpath + '/vertices/' 18 | inputfileE = inputpath + '/edges/' 19 | } 20 | 21 | authorInput = File.json(inputfileV + 'author.json') 22 | bookInput = File.json(inputfileV + 'book.json') 23 | authorBookInput = File.json(inputfileE + 'authorBook.json') 24 | 25 | //Specifies what data source to load using which mapper (as defined inline) 26 | 27 | load(authorInput).asVertices { 28 | label "author" 29 | key "name" 30 | } 31 | 32 | load(bookInput).asVertices { 33 | label "book" 34 | key "name" 35 | } 36 | 37 | load(authorBookInput).asEdges { 38 | label "authored" 39 | outV "aname", { 40 | label "author" 41 | key "name" 42 | } 43 | inV "bname", { 44 | label "book" 45 | key "name" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /documentation-examples/JSON/data/edges/authorBook.json: -------------------------------------------------------------------------------- 1 | {"bname":"The Art of French Cooking, Vol. 1","aname":"Julia Child"} 2 | {"bname":"The Art of French Cooking, Vol. 1","aname":"Simone Beck"} 3 | {"bname":"The Art of French Cooking, Vol. 1","aname":"Louisette Bertholie"} 4 | {"bname":"Simca's Cuisine: 100 Classic French Recipes for Every Occasion","aname":"Simone Beck"} 5 | {"bname":"Simca's Cuisine: 100 Classic French Recipes for Every Occasion","aname":"Patricia Simon"} 6 | {"bname":"The French Chef Cookbook","aname":"Julia Child"} 7 | {"bname":"The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution","aname":"Alice Waters"} 8 | {"bname":"The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution","aname":"Patricia Curtan"} 9 | {"bname":"The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution","aname":"Kelsie Kerr"} 10 | {"bname":"The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution","aname":"Fritz Streiff"} 11 | -------------------------------------------------------------------------------- /documentation-examples/JSON/data/vertices/author.json: -------------------------------------------------------------------------------- 1 | {"name":"Julia Child","gender":"F"} 2 | {"name":"Simone Beck","gender":"F"} 3 | {"name":"Louisette Bertholie","gender":"F"} 4 | {"name":"Patricia Simon","gender":"F"} 5 | {"name":"Alice Waters","gender":"F"} 6 | {"name":"Patricia Curtan","gender":"F"} 7 | {"name":"Kelsie Kerr","gender":"F"} 8 | {"name":"Fritz Streiff","gender":"M"} 9 | {"name":"Emeril Lagasse","gender":"M"} 10 | {"name":"James Beard","gender":"M"} 11 | -------------------------------------------------------------------------------- /documentation-examples/JSON/data/vertices/book.json: -------------------------------------------------------------------------------- 1 | {"name":"The Art of French Cooking, Vol. 1","year":1961,"ISBN":"none"} 2 | {"name":"Simca's Cuisine: 100 Classic French Recipes for Every Occasion","year":1972,"ISBN":"0-394-40152-2"} 3 | {"name":"The French Chef Cookbook","year":1968,"ISBN":"0-394-40135-2"} 4 | {"name":"The Art of Simple Food: Notes, Lessons, and Recipes from a Delicious Revolution","year":2007,"ISBN":"0-307-33679-4"} 5 | -------------------------------------------------------------------------------- /documentation-examples/JSON/graphloader_command.txt: -------------------------------------------------------------------------------- 1 | # change paths 2 | /path/to/graphloader /path/to/authorBookMap_JSON.groovy -graph testJSON -address localhost -abort_on_prep_errors false -inputpath /path/to/directory/containing/data 3 | -------------------------------------------------------------------------------- /documentation-examples/JSON/readme.md: -------------------------------------------------------------------------------- 1 | ## Simple JSON example using authors and books 2 | * [Mapping script] (authorBookMappingJSON.groovy) 3 | * [schema] (schema.groovy) 4 | * [verify.groovy] (a verification script) 5 | * [graphloader instructions] (graphloader_command.txt) 6 | * [author.json] (author.json) 7 | * [book.json] (book.json) 8 | * [authorBook.json - edges] (authorBook.json) 9 | -------------------------------------------------------------------------------- /documentation-examples/JSON/schema.groovy: -------------------------------------------------------------------------------- 1 | //system.graph('testJSON').ifNotExists().create() 2 | //:remote config alias g testJSON.g 3 | //schema.clear() 4 | //schema.config().option('graph.allow_scan').set('true') 5 | 6 | // SCHEMA 7 | // PROPERTIES 8 | schema.propertyKey('name').Text().ifNotExists().create() 9 | schema.propertyKey('nickname').Text().ifNotExists().create() 10 | schema.propertyKey('gender').Text().ifNotExists().create() 11 | schema.propertyKey('year').Int().ifNotExists().create() 12 | schema.propertyKey('ISBN').Text().ifNotExists().create() 13 | // VERTEX LABELS 14 | schema.vertexLabel('author').properties('name','gender','nickname').ifNotExists().create() 15 | schema.vertexLabel('book').properties('name','year', 'ISBN').ifNotExists().create() 16 | // EDGE LABELS 17 | schema.edgeLabel('authored').connection('author','book').ifNotExists().create() 18 | // INDEXES 19 | schema.vertexLabel('book').index('byname').materialized().by('name').add() 20 | schema.vertexLabel('author').index('byname').materialized().by('name').add() 21 | schema.vertexLabel('book').index('search').search().by('name').asString().by('year').add() 22 | -------------------------------------------------------------------------------- /documentation-examples/JSON/verify.groovy: -------------------------------------------------------------------------------- 1 | g.V().count()|14 2 | g.E().count()|10 3 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/filePatternCSVMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | CSV: 3 | id|name|gender 4 | 001|Julia Child|F 5 | */ 6 | 7 | // CONFIGURATION 8 | // Configures the data loader to create the schema 9 | config dryrun: false, preparation: true, create_schema: false, load_new: true, schema_output: 'loader_output.txt' 10 | 11 | // DATA INPUT 12 | // Define the data input source (a file which can be specified via command line arguments) 13 | // inputfiledir is the directory for the input files 14 | 15 | inputfiledir = '/tmp/filePattern/data' 16 | personInput = File.directory(inputfiledir).fileMatches("person*.csv").delimiter('|').header('id','name','gender') 17 | 18 | //Specifies what data source to load using which mapper (as defined inline) 19 | 20 | load(personInput).asVertices { 21 | label "person" 22 | key "name" 23 | } 24 | 25 | /* RESULT: 26 | person1.csv and person2.csv will be loaded, but not badOne.csv 27 | */ 28 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/filePatternJSONMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | {"name":"Julia Child","gender":"F"} 3 | */ 4 | 5 | // CONFIGURATION 6 | // Configures the data loader to create the schema 7 | config dryrun: false, preparation: true, create_schema: false, load_new: true, schema_output: 'loader_output.txt' 8 | 9 | // DATA INPUT 10 | // Define the data input source (a file which can be specified via command line arguments) 11 | // inputfiledir is the directory for the input files 12 | 13 | inputfiledir = '/tmp/filePattern/data_json' 14 | personInput = File.directory(inputfiledir).fileMatches("person*.json") 15 | 16 | //Specifies what data source to load using which mapper (as defined inline) 17 | 18 | load(personInput).asVertices { 19 | label "person" 20 | key "name" 21 | } 22 | 23 | /* RESULT: 24 | person1.json and person2.json will be loaded, but not badOne.json 25 | */ 26 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/filePatternMULTMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | id|name|gender 3 | 001|Julia Child|F 4 | */ 5 | 6 | // CONFIGURATION 7 | // Configures the data loader to create the schema 8 | config dryrun: false, preparation: true, create_schema: false, load_new: true, schema_output: 'loader_output.txt' 9 | 10 | // DATA INPUT 11 | // Define the data input source (a file which can be specified via command line arguments) 12 | // inputfiledir is the directory for the input files 13 | 14 | inputfiledir = '/tmp/filePattern/data' 15 | personInput = File.directory(inputfiledir).fileMatches("{person*,badOne}.csv").delimiter('|').header('id','name','gender') 16 | 17 | //Specifies what data source to load using which mapper (as defined inline) 18 | 19 | load(personInput).asVertices { 20 | label "person" 21 | key "name" 22 | } 23 | 24 | /* RESULT: 25 | person1.csv, person2.csv and badOne.csv will all be loaded 26 | */ 27 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/filePatternQUESTMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | CSV: 3 | id|name|gender 4 | 001|Julia Child|F 5 | */ 6 | 7 | // CONFIGURATION 8 | // Configures the data loader to create the schema 9 | config dryrun: false, preparation: true, create_schema: false, load_new: true, schema_output: 'loader_output.txt' 10 | 11 | // DATA INPUT 12 | // Define the data input source (a file which can be specified via command line arguments) 13 | // inputfiledir is the directory for the input files 14 | 15 | inputfiledir = '/tmp/filePattern/data' 16 | personInput = File.directory(inputfiledir).fileMatches("person?.csv").delimiter('|').header('id','name','gender') 17 | 18 | //Specifies what data source to load using which mapper (as defined inline) 19 | 20 | load(personInput).asVertices { 21 | label "person" 22 | key "name" 23 | } 24 | 25 | /* RESULT: 26 | person1.csv and person2.csv will be loaded, but not badOne.csv 27 | */ 28 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/filePatternRANGEMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | id|name|gender 3 | 001|Julia Child|F 4 | */ 5 | 6 | // CONFIGURATION 7 | // Configures the data loader to create the schema 8 | config dryrun: false, preparation: true, create_schema: false, load_new: true, schema_output: 'loader_output.txt' 9 | 10 | // DATA INPUT 11 | // Define the data input source (a file which can be specified via command line arguments) 12 | // inputfiledir is the directory for the input files 13 | 14 | inputfiledir = '/tmp/filePattern/data' 15 | personInput = File.directory(inputfiledir).fileMatches("person[1-9].csv").delimiter('|').header('id','name','gender') 16 | 17 | //Specifies what data source to load using which mapper (as defined inline) 18 | 19 | load(personInput).asVertices { 20 | label "person" 21 | key "name" 22 | } 23 | 24 | /* RESULT: 25 | person1.csv and person2.csv will be loaded, but not badOne.csv 26 | */ 27 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/queries.groovy: -------------------------------------------------------------------------------- 1 | // CSV 2 | :remote config alias g testFilePatCSV.g 3 | schema.config().option('graph.allow_scan').set('true') 4 | g.V().valueMap() 5 | 6 | // JSON 7 | :remote config alias g testFilePatJSON.g 8 | schema.config().option('graph.allow_scan').set('true') 9 | g.V().valueMap() 10 | 11 | // MULT 12 | :remote config alias g testFilePatMULT.g 13 | schema.config().option('graph.allow_scan').set('true') 14 | g.V().valueMap() 15 | 16 | // RANGE 17 | :remote config alias g testFilePatRANGE.g 18 | schema.config().option('graph.allow_scan').set('true') 19 | g.V().valueMap() 20 | 21 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/readme.md: -------------------------------------------------------------------------------- 1 | ## Simple read from multiple files in a directory example 2 | * [Map script - CSV] (filePatternCSVMap.groovy) 3 | * [Map script - JSON] (filePatternJSONMap.groovy) 4 | * [Map script - Multiple matches] (filePatternMULTMap.groovy) 5 | * [Map script - Range matches] (filePatternRANGEMap.groovy) 6 | * [Map script - Questionmark matches] (filePatternQUESTMap.groovy) 7 | * [schema] (schema.groovy) 8 | * [graphloader script] (runDGL.sh) 9 | * [data] (data) 10 | * [person1.csv] (data/person.csv) 11 | * [person2.csv] (data/person2.csv) 12 | * [badOne.csv - used for testing file pattern] (data/badOne.csv) 13 | * [data_json] (data_json) 14 | * [person1.csv] (data/person1.csv) 15 | * [person2.csv] (data/person2.csv) 16 | * [badOne.csv - used for testing file pattern] (data/badOne.csv) 17 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.1.2-SNAPSHOT 13 | LDR=/$VERSION/graphloader 14 | INPUTEXAMPLE='filePattern' 15 | INPUTBASEDIR='/tmp' 16 | INPUTFILEDIR=$INPUTBASEDIR/$INPUTEXAMPLE/ 17 | echo $INPUTFILEDIR 18 | 19 | # CSV 20 | SCRIPTNAME1=$INPUTEXAMPLE'CSVMap.groovy' 21 | echo $SCRIPTNAME1 22 | GRAPHNAME1='testFilePatCSV' 23 | $LDR $INPUTFILEDIR/$SCRIPTNAME1 -graph $GRAPHNAME1 -address localhost 24 | 25 | # JSON 26 | SCRIPTNAME2=$INPUTEXAMPLE'JSONMap.groovy' 27 | echo $SCRIPTNAME2 28 | GRAPHNAME2='testFilePatJSON' 29 | $LDR $INPUTFILEDIR/$SCRIPTNAME2 -graph $GRAPHNAME2 -address localhost 30 | 31 | # MULT 32 | SCRIPTNAME3=$INPUTEXAMPLE'MULTMap.groovy' 33 | echo $SCRIPTNAME3 34 | GRAPHNAME3='testFilePatMULT' 35 | $LDR $INPUTFILEDIR/$SCRIPTNAME3 -graph $GRAPHNAME3 -address localhost 36 | 37 | # RANGE 38 | SCRIPTNAME4=$INPUTEXAMPLE'RANGEMap.groovy' 39 | echo $SCRIPTNAME4 40 | GRAPHNAME4='testFilePatRANGE' 41 | $LDR $INPUTFILEDIR/$SCRIPTNAME4 -graph $GRAPHNAME4 -address localhost 42 | 43 | # QUEST 44 | SCRIPTNAME5=$INPUTEXAMPLE'QUESTMap.groovy' 45 | echo $SCRIPTNAME5 46 | GRAPHNAME5='testFilePatQUEST' 47 | $LDR $INPUTFILEDIR/$SCRIPTNAME5 -graph $GRAPHNAME5 -address localhost 48 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filePattern/schema.groovy: -------------------------------------------------------------------------------- 1 | // CSV 2 | system.graph('testFilePatCSV').ifNotExists().create() 3 | :remote config alias g testFilePatCSV.g 4 | schema.config().option('graph.allow_scan').set('true') 5 | 6 | // SCHEMA 7 | // PROPERTIES 8 | schema.propertyKey('id').Text().ifNotExists().create() 9 | schema.propertyKey('name').Text().ifNotExists().create() 10 | schema.propertyKey('gender').Text().ifNotExists().create() 11 | // VERTEX LABELS 12 | schema.vertexLabel('person').properties('id', 'name', 'gender').ifNotExists().create() 13 | // INDEXES 14 | schema.vertexLabel("person").index("byid").materialized().by("id").add() 15 | schema.vertexLabel("person").index("byname").materialized().by("name").add() 16 | 17 | // JSON 18 | system.graph('testFilePatJSON').ifNotExists().create() 19 | :remote config alias g testFilePatJSON.g 20 | schema.config().option('graph.allow_scan').set('true') 21 | 22 | // SCHEMA 23 | // PROPERTIES 24 | schema.propertyKey('id').Text().ifNotExists().create() 25 | schema.propertyKey('name').Text().ifNotExists().create() 26 | schema.propertyKey('gender').Text().ifNotExists().create() 27 | // VERTEX LABELS 28 | schema.vertexLabel('person').properties('id', 'name', 'gender').ifNotExists().create() 29 | // INDEXES 30 | schema.vertexLabel("person").index("byid").materialized().by("id").add() 31 | schema.vertexLabel("person").index("byname").materialized().by("name").add() 32 | 33 | // MATCH MULTIPLE FILENAME PATTERNS 34 | system.graph('testFilePatMULT').ifNotExists().create() 35 | :remote config alias g testFilePatMULT.g 36 | schema.config().option('graph.allow_scan').set('true') 37 | 38 | // SCHEMA 39 | // PROPERTIES 40 | schema.propertyKey('id').Text().ifNotExists().create() 41 | schema.propertyKey('name').Text().ifNotExists().create() 42 | schema.propertyKey('gender').Text().ifNotExists().create() 43 | // VERTEX LABELS 44 | schema.vertexLabel('person').properties('id', 'name', 'gender').ifNotExists().create() 45 | // INDEXES 46 | schema.vertexLabel("person").index("byid").materialized().by("id").add() 47 | schema.vertexLabel("person").index("byname").materialized().by("name").add() 48 | 49 | // MATCH RANGE PATTERN 50 | system.graph('testFilePatRANGE').ifNotExists().create() 51 | :remote config alias g testFilePatRANGE.g 52 | schema.config().option('graph.allow_scan').set('true') 53 | 54 | // SCHEMA 55 | // PROPERTIES 56 | schema.propertyKey('id').Text().ifNotExists().create() 57 | schema.propertyKey('name').Text().ifNotExists().create() 58 | schema.propertyKey('gender').Text().ifNotExists().create() 59 | // VERTEX LABELS 60 | schema.vertexLabel('person').properties('id', 'name', 'gender').ifNotExists().create() 61 | // INDEXES 62 | schema.vertexLabel("person").index("byid").materialized().by("id").add() 63 | schema.vertexLabel("person").index("byname").materialized().by("name").add() 64 | 65 | // QUESTION MARK PATTERN 66 | system.graph('testFilePatQUEST').ifNotExists().create() 67 | :remote config alias g testFilePatQUEST.g 68 | schema.config().option('graph.allow_scan').set('true') 69 | 70 | // SCHEMA 71 | // PROPERTIES 72 | schema.propertyKey('id').Text().ifNotExists().create() 73 | schema.propertyKey('name').Text().ifNotExists().create() 74 | schema.propertyKey('gender').Text().ifNotExists().create() 75 | // VERTEX LABELS 76 | schema.vertexLabel('person').properties('id', 'name', 'gender').ifNotExists().create() 77 | // INDEXES 78 | schema.vertexLabel("person").index("byid").materialized().by("id").add() 79 | schema.vertexLabel("person").index("byname").materialized().by("name").add() 80 | 81 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/filterData.csv: -------------------------------------------------------------------------------- 1 | name|gender|status|age 2 | Julia Child|F|deceased|500 3 | Simone Beck|F|deceased|500 4 | Louisette Bertholie|F|deceased|500 5 | Patricia Simon|F|deceased|500 6 | Alice Waters|F|alive|73 7 | Patricia Curtan|F|alive|66 8 | Kelsie Kerr|F|alive|57 9 | Fritz Streiff|M|alive|500 10 | Emeril Lagasse|M|alive|57 11 | James Beard|M|deceased|500 12 | Jamie Oliver|M|alive|41 13 | Amanda Cohen|F|alive|35 14 | Patrick Connolly|M|alive|31 15 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/filterMap.groovy: -------------------------------------------------------------------------------- 1 | /** SAMPLE INPUT 2 | name|gender|status|age 3 | Jamie Oliver|M|alive|41 4 | **/ 5 | 6 | // CONFIGURATION 7 | // Configures the data loader to create the schema 8 | config create_schema: false, load_new: true 9 | 10 | // DATA INPUT 11 | // Define the data input source (a file which can be specified via command line arguments) 12 | // inputfiledir is the directory for the input files that is given in the commandline 13 | // as the "-filename" option 14 | 15 | inputfiledir = 'graph-examples/documentation-examples/MISC/filter_map_flatmap/' 16 | chefs = File.csv(inputfiledir + "filterData.csv").delimiter('|') 17 | def chefsYoung = chefs.filter { it["age"].toInteger() <= 41 } 18 | def chefsAlive = chefs.filter { it["status"] == "alive" } 19 | def chefsDeceased = chefs.filter { it["status"] == "deceased" } 20 | 21 | //Specifies what data source to load using which mapper (as defined inline) 22 | load(chefsAlive).asVertices { 23 | label "chefAlive" 24 | key "name" 25 | } 26 | 27 | load(chefsDeceased).asVertices { 28 | label "chefDeceased" 29 | key "name" 30 | } 31 | 32 | load(chefsYoung).asVertices { 33 | label "chefYoung" 34 | key "name" 35 | } 36 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/filterQueries.groovy: -------------------------------------------------------------------------------- 1 | :remote config alias g filterTest.g 2 | schema.config().option('graph.allow_scan').set('true') 3 | 4 | // List all the vertices 5 | g.V() 6 | 7 | // List all the living chefs 8 | g.V().hasLabel('chefAlive').valueMap() 9 | 10 | // List all the deceased chefs 11 | g.V().hasLabel('chefDeceased').valueMap() 12 | 13 | // List all the chefs 41 years old and younger 14 | g.V().hasLabel('chefYoung').valueMap() 15 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/filterSchema.groovy: -------------------------------------------------------------------------------- 1 | system.graph('filterTest').ifNotExists().create() 2 | :remote config alias g filterTest.g 3 | schema.clear() 4 | schema.config().option('graph.allow_scan').set('true') 5 | 6 | schema.propertyKey('name').Text().ifNotExists().create() 7 | schema.propertyKey('gender').Text().ifNotExists().create() 8 | schema.propertyKey('status').Text().ifNotExists().create() 9 | schema.propertyKey('age').Int().ifNotExists().create() 10 | 11 | schema.vertexLabel('chefAlive').properties('name','gender','status','age').create() 12 | schema.vertexLabel('chefAlive').index('byname').materialized().by('name').add() 13 | schema.vertexLabel('chefDeceased').properties('name','gender','status','age').create() 14 | schema.vertexLabel('chefDeceased').index('byname').materialized().by('name').add() 15 | schema.vertexLabel('chefYoung').properties('name','gender','status','age').create() 16 | schema.vertexLabel('chefYoung').index('byname').materialized().by('name').add() 17 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/flatmapData.csv: -------------------------------------------------------------------------------- 1 | name|cuisine 2 | Beef Bourguignon|English::French 3 | Nicoise Salade|French 4 | Wild Mushroom Stroganoff|American::English 5 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/flatmapMap.groovy: -------------------------------------------------------------------------------- 1 | /** SAMPLE INPUT 2 | name|cuisine 3 | Beef Bourguignon|English::French 4 | **/ 5 | 6 | // CONFIGURATION 7 | // Configures the data loader to create the schema 8 | config create_schema: false, load_new: true 9 | 10 | // DATA INPUT 11 | // Define the data input source (a file which can be specified via command line arguments) 12 | // inputfiledir is the directory for the input files that is given in the commandline 13 | // as the "-filename" option 14 | 15 | inputfiledir = 'graph-examples/documentation-examples/MISC/filter_map_flatmap/' 16 | recipes = File.csv(inputfiledir + "flatmapData.csv").delimiter('|') 17 | def recipesCuisine = recipes.flatMap { 18 | def name = it["name"]; 19 | it["cuisine"].split("::"). 20 | collect { it = [ 'name': name, 'cuisine': it ] } 21 | } 22 | //Specifies what data source to load using which mapper (as defined inline) 23 | load(recipesCuisine).asVertices { 24 | label "recipe" 25 | key name: "name", cuisine: "cuisine" 26 | } 27 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/flatmapQueries.groovy: -------------------------------------------------------------------------------- 1 | :remote config alias g flatmapTest.g 2 | schema.config().option('graph.allow_scan').set('true') 3 | 4 | schema.describe() 5 | g.V().count() 6 | g.V().valueMap() 7 | g.V() 8 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/flatmapSchema.groovy: -------------------------------------------------------------------------------- 1 | system.graph('flatmapTest').ifNotExists().create() 2 | :remote config alias g flatmapTest.g 3 | schema.clear() 4 | schema.config().option('graph.allow_scan').set('true') 5 | 6 | schema.propertyKey('name').Text().ifNotExists().create() 7 | schema.propertyKey('cuisine').Text().ifNotExists().create() 8 | 9 | schema.vertexLabel('recipe').properties('name','cuisine').create() 10 | schema.vertexLabel('recipe').index('byname').materialized().by('name').add() 11 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/graphloaderFilter.txt: -------------------------------------------------------------------------------- 1 | graphloader -address localhost -graph filterTest filterMap.groovy 2 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/graphloaderFlatmap.txt: -------------------------------------------------------------------------------- 1 | graphloader -address localhost -graph flatmapTest flatmapMap.groovy 2 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/mapData.csv: -------------------------------------------------------------------------------- 1 | name|gender|age 2 | Julia Child|F|500 3 | Simone Beck|F|500 4 | Louisette Bertholie|F|500 5 | Patricia Simon|F|500 6 | Alice Waters|F|73 7 | Patricia Curtan|F|66 8 | Kelsie Kerr|F|57 9 | Fritz Streiff|M|500 10 | Emeril Lagasse|M|57 11 | James Beard|M|500 12 | Jamie Oliver|M|41 13 | Amanda Cohen|F|35 14 | Patrick Connolly|M|31 15 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/mapMap.groovy: -------------------------------------------------------------------------------- 1 | /** SAMPLE INPUT 2 | name|gender|age 3 | Jamie Oliver|M|41 4 | **/ 5 | 6 | // CONFIGURATION 7 | // Configures the data loader to create the schema 8 | config create_schema: false, load_new: true 9 | 10 | // DATA INPUT 11 | // Define the data input source (a file which can be specified via command line arguments) 12 | // inputfiledir is the directory for the input files that is given in the commandline 13 | // as the "-filename" option 14 | 15 | inputfiledir = '/home/automaton/graph-examples/food/TEST/filter_map_flatmap/' 16 | chefs = File.csv(inputfiledir + "mapData.csv").delimiter('|') 17 | chefInput = chefs.map { it['gender'] = it['gender'].toLowerCase(); it } 18 | 19 | //Specifies what data source to load using which mapper (as defined inline) 20 | 21 | load(chefInput).asVertices { 22 | label "chef" 23 | key "name" 24 | } 25 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/mapQueries.groovy: -------------------------------------------------------------------------------- 1 | :remote config alias g mapTest.g 2 | schema.config().option('graph.allow_scan').set('true') 3 | 4 | // List all the vertices 5 | g.V() 6 | 7 | // List all the chefs 8 | g.V().valueMap() 9 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/mapSchema.csv: -------------------------------------------------------------------------------- 1 | system.graph('mapTest').ifNotExists().create() 2 | :remote config alias g mapTest.g 3 | schema.clear() 4 | schema.config().option('graph.allow_scan').set('true') 5 | 6 | schema.propertyKey('name').Text().ifNotExists().create() 7 | schema.propertyKey('gender').Text().ifNotExists().create() 8 | schema.propertyKey('age').Int().ifNotExists().create() 9 | 10 | schema.vertexLabel('chef').properties('name','gender','age').create() 11 | schema.vertexLabel('chef').index('byname').materialized().by('name').add() 12 | -------------------------------------------------------------------------------- /documentation-examples/MISC/filter_map_flatmap/readme.md: -------------------------------------------------------------------------------- 1 | ## Filter, Map, and Flatmap 2 | * [filterSchema] (filterSchema.groovy) 3 | * [flatmapSchema] (flatmapSchema.groovy) 4 | * [mapSchema] (mapSchema.groovy) 5 | * [filterData.groovy] (filterData.groovy) 6 | * [flatmapData.groovy] (flatmapData.groovy) 7 | * [mapData.groovy] (mapData.groovy) 8 | * [filterQueries.groovy] (filterQueries.groovy) 9 | * [flatmapQueries.groovy] (flatmapQueries.groovy) 10 | * [mapQueries.groovy] (mapQueries.groovy) 11 | * [graphloaderFilter.text] (graphloaderFilter.txt) 12 | * [graphloaderFlatmap.text] (graphloaderFlatmap.txt) 13 | * [graphloaderMap.text] (graphloaderMap.txt) 14 | -------------------------------------------------------------------------------- /documentation-examples/MISC/metaProperty/data.groovy: -------------------------------------------------------------------------------- 1 | // One way to add data 2 | julia=graph.addVertex(label,'author', 'name', 'Julia Child') 3 | props=julia.property(list,'country','France') 4 | props.property('start_date', '1950-01-01') 5 | props.property('end_date', '1960-12-31') 6 | props2 = julia.property(list, 'country', 'USA') 7 | props2.property('start_date', '1961-01-01') 8 | props2.property('end_date', '1984-06-23') 9 | 10 | // Another way to add data 11 | g.addV('author'). 12 | property('name', 'Emeril'). 13 | property('country', 'France', 'start_date', '1970-04-05', 'end_date','1973-09-09'). 14 | property('country', 'USA', 'start_date', '1973-02-02', 'end_date', '2017-03-01') 15 | -------------------------------------------------------------------------------- /documentation-examples/MISC/metaProperty/queries.groovy: -------------------------------------------------------------------------------- 1 | // Find the properties (countries) 2 | g.V().properties() 3 | 4 | // Find the properties of the properties (start_dates and end_dates) 5 | g.V().properties().properties() 6 | 7 | // Find the values for the start_date/end_date for all France entries 8 | g.V().properties('country').hasValue('France').properties().value() 9 | 10 | // Find the start_date for each country, for each author 11 | g.V().as('author'). 12 | properties('country').as('country'). 13 | has('start_date').as('start_living_in'). 14 | select('author','country','start_living_in'). 15 | by('name'). 16 | by(value). 17 | by('start_date') 18 | -------------------------------------------------------------------------------- /documentation-examples/MISC/metaProperty/readme.md: -------------------------------------------------------------------------------- 1 | ## Meta-property 2 | * [schema] (schema.groovy) 3 | * [data.groovy] (data.groovy) 4 | * [queries.groovy] (queries.groovy) 5 | -------------------------------------------------------------------------------- /documentation-examples/MISC/metaProperty/schema.groovy: -------------------------------------------------------------------------------- 1 | schema.propertyKey("name").Text().single().create() 2 | schema.propertyKey('start_date').Date().create() 3 | schema.propertyKey('end_date').Date().create() 4 | schema.propertyKey('country').Text().multiple().properties('start_date','end_date').create() 5 | schema.vertexLabel("author").properties("name", 'country').create() 6 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/authorCity.csv: -------------------------------------------------------------------------------- 1 | author|city|dateStart|dateEnd 2 | Julia Child|Paris|1961-01-01|1967-02-10 3 | Julia Child|New York|1970-06-06|1971-09-23 4 | Julia Child|Chicago|1980-04-05|1981-01-01 5 | Julia Child|Paris|1990-01-01|1991-01-01 6 | Simone Beck|Paris|1960-01-01|1962-09-23 7 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/multiCardMap.groovy: -------------------------------------------------------------------------------- 1 | /* SAMPLE INPUT 2 | authorCity: 3 | author|city|dateStart|dateEnd 4 | i 5 | Julia Child|Paris|1961-01-01|1967-02-10 6 | */ 7 | 8 | // CONFIGURATION 9 | // Configures the data loader to create the schema 10 | config dryrun: false, preparation: true, create_schema: true, load_new: true, schema_output: 'loader_output.txt' 11 | 12 | // DATA INPUT 13 | // Define the data input source (a file which can be specified via command line arguments) 14 | // inputfiledir is the directory for the input files 15 | inputfiledir = '/graph-examples/documentation-examples/MISC/multiCard/' 16 | authorCityInput = File.csv(inputfiledir + "authorCity.csv").delimiter('|') 17 | 18 | //Specifies what data source to load using which mapper (as defined inline) 19 | 20 | load(authorCityInput).asVertices { 21 | label "author" 22 | key "author" 23 | ignore "city" 24 | ignore "dateStart" 25 | ignore "dateEnd" 26 | } 27 | 28 | load(authorCityInput).asVertices { 29 | label "city" 30 | key "city" 31 | ignore "author" 32 | ignore "dateStart" 33 | ignore "dateEnd" 34 | } 35 | 36 | load(authorCityInput).asEdges { 37 | label "livedIn" 38 | outV "author", { 39 | label "author" 40 | key "author" 41 | } 42 | inV "city", { 43 | label "city" 44 | key "city" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/query.groovy: -------------------------------------------------------------------------------- 1 | // Print outgoing edges 2 | g.V().outE() 3 | 4 | // Find all outgoing edges with a start date of Jan 1, 1960 5 | g.V().outE().has('dateStart', '1960-01-01') 6 | 7 | // Find the vertices at the end of the outgoing edges in the last query 8 | g.V().outE().has('dateStart', '1960-01-01').outV() 9 | 10 | // Get a value map of all the values for the vertices in the last query 11 | g.V().outE().has('dateStart', '1960-01-01').outV().valueMap() 12 | 13 | // Change the query to find all the values where the start date is later than Jan 1, 1960 14 | g.V().outE().has('dateStart', gt('1960-01-01')).outV().valueMap() 15 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/readme.md: -------------------------------------------------------------------------------- 1 | ## Simple CSV example using authors and books 2 | * [Mapping script] (multiCardMap.groovy) 3 | * [schema] (schema.groovy) 4 | * [graphloader script] (runDGL.sh) 5 | * [authorCity.csv] (authorCity.csv) 6 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/runDGL.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # VERSION defines the graphloader version 3 | # LDR defines the graphloader path 4 | # TYPE defines the input type. Values are: TEXT, CSV, JSON, TEXTXFORM 5 | # INPUTEXAMPLE defines the mapping example 6 | # INPUTBASEDIR defines the main directory of the examples 7 | # INPUTFILEDIR defines the directory of the input files 8 | # SCRIPTNAME defines the name of the mapping script 9 | # GRAPHNAME defines the name of the graph loaded. 10 | # It does not have to exist prior to loading. 11 | 12 | VERSION=dse-graph-loader-5.0.5 13 | LDR=/$VERSION/graphloader 14 | TYPE=MISC 15 | INPUTEXAMPLE='multiCard' 16 | INPUTBASEDIR='/graph-examples/documentation-examples' 17 | INPUTFILEDIR=$INPUTBASEDIR/$TYPE/$INPUTEXAMPLE 18 | SCRIPTNAME='multiCardMap.groovy' 19 | GRAPHNAME='test'$INPUTEXAMPLE 20 | $LDR $INPUTFILEDIR/$SCRIPTNAME -graph $GRAPHNAME -address localhost 21 | -------------------------------------------------------------------------------- /documentation-examples/MISC/multiCard/schema.groovy: -------------------------------------------------------------------------------- 1 | // SCHEMA 2 | // PROPERTIES 3 | schema.propertyKey('author').Text().single().create() 4 | schema.propertyKey('city').Text().single().create() 5 | schema.propertyKey('dateStart').Text().single().create() 6 | schema.propertyKey('dateEnd').Text().single().create() 7 | // VERTEX LABELS 8 | schema.vertexLabel('author').properties('author').create() 9 | schema.vertexLabel('city').properties('city').create() 10 | // EDGE LABELS 11 | schema.edgeLabel('livedIn').multiple().connection('author','city').create() 12 | schema.edgeLabel('livedIn').properties('dateStart', 'dateEnd').add() 13 | // INDEXES 14 | schema.vertexLabel('author').index('byAuthor').materialized().by('author').add() 15 | schema.vertexLabel('city').index('byCity').materialized().by('city').add() 16 | schema.vertexLabel('author').index('byStartDate').outE('livedIn').by('dateStart').add() 17 | -------------------------------------------------------------------------------- /documentation-examples/MISC/readme.md: -------------------------------------------------------------------------------- 1 | # MISC Examples 2 | * [Meta-property: meta-properties are properties of a property] (metaProperty/readme.md) 3 | * [Multi-cardinality: multi-cardinality of edges] (multiCard/readme.md) 4 | * [Filter-Map-Flatmap examples] (filter_map_flatmap/readme.md) 5 | * [File patterns for loading data] (filePattern/readme.md) 6 | -------------------------------------------------------------------------------- /documentation-examples/readme.md: -------------------------------------------------------------------------------- 1 | # Documentation Examples 2 | 3 | All examples included in this directory are included in [DataStax's documentation] (http://docs.datastax.com/en/latest-dse/datastax_enterprise/graph/graphTOC.html). 4 | * [CSV Examples] (CSV/readme.md) 5 | * [JSON Examples] (JSON/readme.md) 6 | -------------------------------------------------------------------------------- /dse-graph-frame/README.md: -------------------------------------------------------------------------------- 1 | # DseGraphFrame example 2 | 3 | This example is described in the blog post [Introducing DSE Graph Frames](http://www.datastax.com/dev/blog/dse-graph-frame). 4 | 5 | `friends-graph.groovy` creates a small 3 vertex graph in DSE Graph. It is used in the following examples. 6 | 7 | `Spark-shell-notes.scala` is a set of manipulations that can be done in Spark shell. The graph commands can be copied and pasted to the shell. 8 | 9 | `build.sbt` and `src/...` are part of a Spark streaming example. 10 | 11 | This generates a random messages stream. The stream is handled and stored in the graph. 12 | 13 | ```bash 14 | sbt package 15 | dse spark-submit target/scala-2.11/dse-graph-frame\_2.11-0.1.jar 16 | ``` -------------------------------------------------------------------------------- /dse-graph-frame/Spark-shell-notes.scala: -------------------------------------------------------------------------------- 1 | import com.datastax.bdp.graph.spark.graphframe._ 2 | import org.apache.spark.sql.SparkSession 3 | import org.apache.spark.sql.functions._ 4 | 5 | import org.apache.tinkerpop.gremlin.process.traversal.P 6 | import org.apache.tinkerpop.gremlin.structure.T 7 | 8 | /** 9 | * The code is stored in the scala class just to get right highliting. 10 | * it is expected to be copy-pasted into spark console 11 | */ 12 | 13 | object Notes extends App { 14 | //not needed in spark-shell 15 | val spark = SparkSession.builder().getOrCreate() 16 | 17 | 18 | // load the graph 19 | val g = spark.dseGraph("test") 20 | g.V.show 21 | g.E.show 22 | 23 | //finding all Josh’s friends of friends: 24 | //Gremlin 25 | g.V.has("name", "josh").out("friend").out("friend").show 26 | //GraphFrame 27 | g.find("(a)-[e]->(b); (b)-[e2]->(c)").filter(" a.name = 'josh' and e.`~label` = 'friend' and e2.`~label` = 'friend'").select("c.*").show 28 | 29 | //drop all 'person' vertices 30 | g.V().hasLabel("person").drop().iterate() 31 | 32 | //use iterators 33 | import scala.collection.JavaConverters._ 34 | for(i <-g.V().id().asScala) println (i) 35 | //get java Set 36 | g.V.id.toSet 37 | 38 | // use TinkerPop predicates 39 | g.V().has("age", P.gt(30)).show 40 | //and ids 41 | g.E().groupCount().by(T.label).show 42 | 43 | // define return type when get properties 44 | g.V().values[Any]("name").next() 45 | g.V().properties[Any]("age", "name").drop().iterate() 46 | 47 | // load verex table directly with Spark source 48 | val df = spark.read.format("com.datastax.bdp.graph.spark.sql.vertex").option("graph", "test").load() 49 | df.show 50 | 51 | // export graph to JSON 52 | g.V.df.write.json("dsefs:///tmp/v_json") 53 | g.E.df.write.json("dsefs:///tmp/e_json") 54 | 55 | //import graph from json to local copy 56 | val g2 = DseGraphFrameBuilder.dseGraph("test", spark.read.json("/tmp/v.json"), spark.read.json("/tmp/e.json")) 57 | 58 | //import graph into C* backend 59 | // do not forget to create schema for new graph 60 | val d = spark.dseGraph("test_import") 61 | d.updateVertices(spark.read.json("/tmp/v.json")) 62 | d.updateEdges(spark.read.json("/tmp/e.json")) 63 | 64 | // import custom graph 65 | val new_data = org.graphframes.examples.Graphs.friends 66 | val v = new_data.vertices.select (col("id") as "_id", lit("person") as "~label", col("name"), col("age")) 67 | val e = new_data.edges.select (g.idColumn(lit("person"), col("src")) as "src", g.idColumn(lit("person"), col("dst")) as "dst", 68 | col("relationship") as "~label") 69 | 70 | g.updateVertices (v) 71 | g.updateEdges (e) 72 | 73 | } 74 | -------------------------------------------------------------------------------- /dse-graph-frame/build.sbt: -------------------------------------------------------------------------------- 1 | name := "dse-graph-frame" 2 | 3 | version := "0.1" 4 | 5 | scalaVersion := "2.11.8" 6 | 7 | // Please make sure that following DSE version matches your DSE cluster version. 8 | val dseVersion = "5.1.2" 9 | 10 | resolvers += "DataStax Repo" at "https://repo.datastax.com/public-repos/" 11 | resolvers += Resolver.mavenLocal // for testing 12 | 13 | mainClass in (Compile, packageBin) := Some("com.datastax.bdp.graphframe.example.StreamingExample") 14 | 15 | // Warning Sbt 0.13.13 or greater is required due to a bug with dependency resolution 16 | libraryDependencies += "com.datastax.dse" % "dse-spark-dependencies" % dseVersion % "provided" 17 | -------------------------------------------------------------------------------- /dse-graph-frame/friends-graph.groovy: -------------------------------------------------------------------------------- 1 | system.graph("test").engine(Classic).create() 2 | 3 | :remote config alias g test.g 4 | //define properties 5 | schema.propertyKey("age").Int().create() 6 | schema.propertyKey("name").Text().create() 7 | schema.propertyKey("id").Text().single().create() 8 | 9 | //define vertex with id property as a custom ID 10 | schema.vertexLabel("person").partitionKey("id").properties("name", "age").create() 11 | // two type of edges without properties 12 | schema.edgeLabel("friend").connection("person", "person").create() 13 | schema.edgeLabel("follow").connection("person", "person").create() 14 | 15 | Vertex marko = graph.addVertex(T.label, "person", "id", "1", "name", "marko", "age", 29) 16 | Vertex vadas = graph.addVertex(T.label, "person", "id", "2", "name", "vadas", "age", 27) 17 | Vertex josh = graph.addVertex(T.label, "person", "id", "3", "name", "josh", "age", 32) 18 | marko.addEdge("friend", vadas) 19 | marko.addEdge("friend", josh) 20 | josh.addEdge("follow", marko) 21 | josh.addEdge("friend", marko) 22 | 23 | 24 | // add one more property for streaming test 25 | schema.propertyKey("messages").Text().multiple().create() 26 | schema.vertexLabel("person").properties("messages").add() -------------------------------------------------------------------------------- /dse-graph-frame/src/main/scala/com/datastax/bdp/graphframe/example/RandomReceiver.scala: -------------------------------------------------------------------------------- 1 | package com.datastax.bdp.graphframe.example 2 | 3 | import org.apache.spark.storage.StorageLevel 4 | import org.apache.spark.streaming.receiver.Receiver 5 | 6 | import scala.util.Random 7 | /** 8 | * Generate random string events for given set of String id. 9 | */ 10 | class RandomReceiver (val ids:Seq[String]) extends Receiver[(String, String)](StorageLevel.MEMORY_ONLY) { 11 | 12 | var stopped = false 13 | 14 | override def onStart(): Unit = { 15 | new Thread(new Runnable() { 16 | override def run() { 17 | try { 18 | while (!stopped) { 19 | Thread.sleep(100) 20 | val msg: (String, String) = (ids(Random.nextInt(ids.length)), s"Hello #${Random.nextInt(100)}") 21 | store(msg) 22 | } 23 | } catch { 24 | case e: InterruptedException => println("Interrupted") 25 | } 26 | } 27 | }, 28 | "RandomReceiver").start(); 29 | } 30 | 31 | override def onStop(): Unit = { 32 | stopped = true 33 | } 34 | 35 | def stop(): Unit = { 36 | stopped = true 37 | } 38 | } -------------------------------------------------------------------------------- /dse-graph-frame/src/main/scala/com/datastax/bdp/graphframe/example/StreamingExample.scala: -------------------------------------------------------------------------------- 1 | package com.datastax.bdp.graphframe.example 2 | 3 | import org.apache.spark.sql.SparkSession 4 | import org.apache.spark.sql.functions._ 5 | 6 | import org.apache.spark.streaming.{Seconds, StreamingContext} 7 | import com.datastax.bdp.graph.spark.graphframe._ 8 | 9 | /** 10 | * Streaming example that read messages from RandomReceiver and store them in "messages" vertex property 11 | */ 12 | 13 | object StreamingExample { 14 | def main(args: Array[String]): Unit = { 15 | val spark = SparkSession.builder() 16 | .config("spark.cleaner.ttl", "3600") 17 | .config("spark.streaming.stopGracefullyOnShutdown","true").getOrCreate() 18 | import spark.implicits._ 19 | 20 | val graph = spark.dseGraph("test") 21 | 22 | val ssc = new StreamingContext(spark.sparkContext, Seconds(1)) 23 | val rec = new RandomReceiver(Seq("1", "2", "3")) 24 | val dstream = ssc.receiverStream(rec) 25 | 26 | dstream.foreachRDD(rdd => { 27 | // convert RDD to proper DF 28 | val updateDF = rdd.toDF("_id", "messages").withColumn("~label", lit("person")) 29 | // update properties 30 | graph.updateVertices(updateDF) 31 | }) 32 | 33 | // debug print received events 34 | dstream.print() 35 | ssc.start() 36 | ssc.awaitTermination() 37 | rec.stop() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /entity-resolution/README.md: -------------------------------------------------------------------------------- 1 | # Entity Recognition Example 2 | 3 | The schema contains two vertices label: person with pasport_id and name as id and master. 4 | The goal of algorithms is to add edges from person nodes to one master node if they have 5 | the same passport id, is used, i. e. 6 | 7 | `(person, passport_id =1, name=Artem) -> (master, passport_id=1, id=xxxx) <-(person, passport_id=1, name=Артем)` 8 | 9 | ## Running the application example: 10 | 11 | `schema.groovy` create empty scheam for simple passport-base ER grpah 12 | run it with gremlin-console 13 | 14 | `dse gremlin-console -e schema.groovy` 15 | 16 | `data` directory contains 3 data files. Put them to the shared file system. 17 | The default location is `dsefs:///tmp` 18 | 19 | ```bash 20 | dse hadoop fs -mkdir dsefs:///tmp 21 | dse hadoop fs -put data/initial.csv data/add_1.csv data/add_2.csv dsefs:///tmp 22 | ``` 23 | 24 | if you test on single node cluster you can pass local filesystem directory with `-d file:///tmp` 25 | 26 | Start the example. spark.sql.crossJoin.enabled is needed only for cartesianRecognizer 27 | 28 | ```bash 29 | sbt package 30 | dse spark-submit --conf spark.sql.crossJoin.enabled=true target/scala-2.11/entity-resolution_2.11-0.1.jar 31 | ``` 32 | 33 | see results in gremlin-console or studio 34 | 35 | ## Running streaming example: 36 | 37 | Streaming example generate random passport id and names, so you'll finally will get a really big graph 38 | ```bash 39 | dse spark-submit --conf spark.sql.crossJoin.enabled=true --class com.datastax.bdp.er.streaming.StreamingExample target/scala-2.11/entity-resolution_2.11-0.1.jar 40 | ``` -------------------------------------------------------------------------------- /entity-resolution/build.sbt: -------------------------------------------------------------------------------- 1 | name := "entity-resolution" 2 | 3 | version := "0.1" 4 | 5 | scalaVersion := "2.11.8" 6 | 7 | // Please make sure that following DSE version matches your DSE cluster version. 8 | val dseVersion = "5.1.2" 9 | 10 | resolvers += "DataStax Repo" at "https://repo.datastax.com/public-repos/" 11 | resolvers += Resolver.mavenLocal // for testing 12 | 13 | mainClass in (Compile, packageBin) := Some("com.datastax.bdp.er.EntityResolutionExample") 14 | 15 | // Warning Sbt 0.13.13 or greater is required due to a bug with dependency resolution 16 | libraryDependencies += "com.datastax.dse" % "dse-spark-dependencies" % dseVersion % "provided" 17 | -------------------------------------------------------------------------------- /entity-resolution/data/add_1.csv: -------------------------------------------------------------------------------- 1 | 4,d 2 | 5,e 3 | 6,f 4 | 10,J 5 | 11,K 6 | 12,L 7 | 1,A 8 | 2,B 9 | 3,C -------------------------------------------------------------------------------- /entity-resolution/data/add_2.csv: -------------------------------------------------------------------------------- 1 | 7,j 2 | 8,h 3 | 9,i 4 | 1,A 5 | 2,B 6 | 3,C -------------------------------------------------------------------------------- /entity-resolution/data/initial.csv: -------------------------------------------------------------------------------- 1 | 1,A 2 | 2,B 3 | 3,C 4 | 4,D 5 | 5,E 6 | 6,F 7 | 7,G 8 | 8,H 9 | 9,I -------------------------------------------------------------------------------- /entity-resolution/schema.groovy: -------------------------------------------------------------------------------- 1 | system.graph("entity").create() 2 | 3 | :remote config alias g entity.g 4 | //define properties 5 | schema.propertyKey("age").Int().single().create() 6 | schema.propertyKey("name").Text().single().create() 7 | schema.propertyKey("passport_id").Text().single().create() 8 | schema.propertyKey("entity_id").Text().single().create() 9 | 10 | schema.vertexLabel("person").partitionKey("passport_id").clusteringKey("name").properties("age").create() 11 | schema.vertexLabel("master").partitionKey("entity_id").properties("passport_id").create() 12 | schema.vertexLabel("master").index("passport_index").secondary().by("passport_id").add() 13 | 14 | schema.edgeLabel("is").single().connection("person", "master").create() 15 | 16 | // examples 17 | //Vertex marko = graph.addVertex(T.label, "person", "passport_id", "a1", "name", "marko", "age", 29) 18 | //Vertex vadas = graph.addVertex(T.label, "person", "passport_id", "a2", "name", "vadas", "age", 27) 19 | //Vertex josh = graph.addVertex(T.label, "person", "passport_id", "a3", "name", "josh", "age", 32) 20 | //Vertex passport = graph.addVertex(T.label,"master" , "entity_id", java.util.UUID.randomUUID().toString() , "passport_id", "a3") 21 | //josh.addEdge("is", passport) 22 | -------------------------------------------------------------------------------- /entity-resolution/src/main/scala/com/datastax/bdp/er/streaming/RandomReceiver.scala: -------------------------------------------------------------------------------- 1 | package com.datastax.bdp.er.streaming 2 | 3 | import org.apache.spark.storage.StorageLevel 4 | import org.apache.spark.streaming.receiver.Receiver 5 | 6 | import scala.util.Random 7 | /** 8 | * Generate random string events for given set of String id. 9 | */ 10 | class RandomReceiver (val PassportNumber:Int = 10000, val NameNumber:Int = 1000) extends Receiver[(String, String)](StorageLevel.MEMORY_ONLY) { 11 | 12 | var stopped = false 13 | 14 | override def onStart(): Unit = { 15 | new Thread(new Runnable() { 16 | override def run() { 17 | try { 18 | while (!stopped) { 19 | val msg: (String, String) = (Random.nextInt(PassportNumber).toString, s"Person #${Random.nextInt(NameNumber)}") 20 | store(msg) 21 | Thread.sleep(100) 22 | } 23 | } catch { 24 | case e: InterruptedException => println("Interrupted") 25 | } 26 | } 27 | }, 28 | "RandomReceiver").start(); 29 | } 30 | 31 | override def onStop(): Unit = { 32 | stopped = true 33 | } 34 | 35 | def stop(): Unit = { 36 | stopped = true 37 | } 38 | } -------------------------------------------------------------------------------- /entity-resolution/src/main/scala/com/datastax/bdp/er/streaming/StreamingExample.scala: -------------------------------------------------------------------------------- 1 | package com.datastax.bdp.er.streaming 2 | 3 | import com.datastax.bdp.er.EntityResolutionExample 4 | import com.datastax.bdp.graph.spark.graphframe._ 5 | import org.apache.spark.sql.functions.udf 6 | import org.apache.spark.sql.{Row, SparkSession} 7 | import org.apache.spark.streaming.{Seconds, StreamingContext} 8 | 9 | /** 10 | * Streaming example that read messages from RandomReceiver and store them in "messages" vertex property 11 | */ 12 | 13 | object StreamingExample { 14 | def main(args: Array[String]): Unit = { 15 | val spark = SparkSession.builder() 16 | .config("spark.cleaner.ttl", "3600") 17 | .config("spark.streaming.stopGracefullyOnShutdown","false").getOrCreate() 18 | import spark.implicits._ 19 | 20 | val graph = spark.dseGraph(EntityResolutionExample.graphName) 21 | 22 | val ssc = new StreamingContext(spark.sparkContext, Seconds(1)) 23 | val rec = new RandomReceiver(PassportNumber = 200, NameNumber = 200) 24 | val dstream = ssc.receiverStream(rec) 25 | 26 | dstream.foreachRDD(rdd => { 27 | // convert RDD to proper DF 28 | val updateDF = rdd.toDF("passport_id", "name") 29 | // update properties 30 | val compareUDF = udf((person: Row, entity: Row) => person.getAs[String]("passport_id") == entity.getAs[String]("passport_id") ) 31 | EntityResolutionExample.cartesianRecognizer(graph,updateDF, compareUDF) 32 | 33 | /* uncomment to switch to gremlin base code. 34 | val searchQuery = 35 | """find = g.V().has("master", "passport_id", passport_id);""" 36 | EntityResolutionExample.gremlinRecognizer(updateDF, searchQuery) 37 | */ 38 | }) 39 | 40 | // debug print received events 41 | dstream.print() 42 | ssc.start() 43 | ssc.awaitTermination() 44 | rec.stop() 45 | System.exit(0) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /fraud/JavaFluentAPI/README.md: -------------------------------------------------------------------------------- 1 | # graph-fraud 2 | Just a simple Graph Fluent API example using a simple Fraud schema defined elsewhere 3 | The application will default to connecting to a DataStax Enterprise cluster using node0 and 4 | insert 2 vertices and an edge between them. The app will then execute a traversal to return the 5 | address for the customer just added. 6 | 7 | To build, execute the following in the JavaFluentAPI directory:: 8 | 9 | ``` 10 | ./build-example.sh 11 | ``` 12 | 13 | Invoke as follows in the JavaFluentAPI directory (by default it connects to `node0): 14 | 15 | ``` 16 | ./run-example.sh 17 | ``` 18 | 19 | or optionally specify a hostname or ip address: 20 | 21 | ``` 22 | ./run-example.sh 1.2.3.4 23 | ``` 24 | -------------------------------------------------------------------------------- /fraud/JavaFluentAPI/build-example.sh: -------------------------------------------------------------------------------- 1 | mvn clean package 2 | -------------------------------------------------------------------------------- /fraud/JavaFluentAPI/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.datastax.fraud 8 | fraud 9 | 1.0-SNAPSHOT 10 | Fraud Graph Sample Code 11 | 12 | 13 | 14 | 15 | com.datastax.dse 16 | dse-java-driver-graph 17 | 1.6.7 18 | 19 | 20 | 21 | ch.qos.logback 22 | logback-classic 23 | 1.0.13 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.1 34 | 35 | 1.8 36 | 1.8 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-assembly-plugin 43 | 2.4.1 44 | 45 | 46 | package 47 | 48 | single 49 | 50 | 51 | 52 | 53 | 54 | com.datastax.fraud.FraudSample 55 | 56 | 57 | 58 | 59 | jar-with-dependencies 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /fraud/JavaFluentAPI/run-example.sh: -------------------------------------------------------------------------------- 1 | java -jar target/fraud-1.0-SNAPSHOT-jar-with-dependencies.jar $1 2 | -------------------------------------------------------------------------------- /fraud/JavaFluentAPI/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.datastax.fraud.FraudSample 3 | 4 | -------------------------------------------------------------------------------- /fraud/data/chargebacks.csv: -------------------------------------------------------------------------------- 1 | chargebacknumber|amount|createdtime|creditcardhashed 2 | 2017033101|150.00|2017-03-30T00:00:00.00Z|a1ab1822888276fdb587a16b2dc7b697 3 | 2017063005|450.00|2017-06-30T00:00:00.00Z|fa7987fa879c789be65426e979cbd976 4 | 2017060244|121.79|2017-06-02T00:00:00.00Z|89149a89f9890e0cd89089e342523f21 -------------------------------------------------------------------------------- /fraud/data/creditCards.csv: -------------------------------------------------------------------------------- 1 | creditcardhashed|type 2 | 5910f4ea0062a0e29afd3dccc741e3ce|visa 3 | 1e91b7046b7f4df53c18e559fb916afa|visa 4 | 579b345a68334b88ef15380719c9be3f|american express 5 | a1ab1822888276fdb587a16b2dc7b697|mastercard 6 | fa7987fa879c789be65426e979cbd976|discover 7 | 84290acb9012e890dd8120cabb9013fe|visa 8 | 89149a89f9890e0cd89089e342523f21|mastercard 9 | 09834915789a89bf4839e8002cc24329|american express 10 | 45748214df934e894ce4893f098149aa|mastercard 11 | 8c934d8e90238A471039432c8234083f|discover 12 | 994d2438ef9ac9204b489302489bbae2|visa -------------------------------------------------------------------------------- /fraud/data/customerAddresses.csv: -------------------------------------------------------------------------------- 1 | customerid|address|city|state|postalcode|countrycode 2 | 10000000-0000-0000-0000-000000000001|101 Adams Lane|Anchorage|AK|99501|US 3 | 10000000-0000-0000-0000-000000000002|102 Bellevue Blvd|Baltimore|MD|21201|US 4 | 10000000-0000-0000-0000-000000000003|103 Charity Court|Cincinatti|OH|45201|US 5 | 10000000-0000-0000-0000-000000000004|104 Dilbert Drive|Detroit|MI|48201|US 6 | 10000000-0000-0000-0000-000000000005|105 Echo Lane|El Paso|TX|79900|US 7 | 10000000-0000-0000-0000-000000000006|106 Felicity Lane|Ft. Lauderdale|FL|33301|US 8 | 10000000-0000-0000-0000-000000000007|107 George Court|Green Bay|WI|54301|US 9 | 10000000-0000-0000-0000-000000000008|108 Harris Avenue|Honolulu|HI|96801|US 10 | 10000000-0000-0000-0000-000000000009|109 Iowa Avenue|Indianapolis|IN|46201|US 11 | 10000000-0000-0000-0000-000000000010|110 Joshua Avenue|Jefferson City|MO|65101|US 12 | 10000000-0000-0000-0000-000000000011|111 Karma Court|Key West|FL|33040|US 13 | 10000000-0000-0000-0000-000000000012|112 Leming Lane|Lafayette|LA|70598|US 14 | 10000000-0000-0000-0000-000000000013|113 Memphis Parkway|Meridian|MS|39301|US 15 | 10000000-0000-0000-0000-000000000014|102 Bellevue Blvd|Baltimore|MD|21201|US 16 | 10000000-0000-0000-0000-000000000015|115 Naples Street|Nunapitchuk|AL|99641|US 17 | 10000000-0000-0000-0000-000000000016|116 Ocean Place|Oklahoma City|OK|73101|US 18 | 10000000-0000-0000-0000-000000000017|117 Pelican Place|Philadelphia|PA|19092|US 19 | 10000000-0000-0000-0000-000000000018|118 Quisenberry Avenue|Queens|NY|11011|US 20 | 10000000-0000-0000-0000-000000000019|119 Reginald Road|Roswell|NM|88201|US 21 | 10000000-0000-0000-0000-000000000020|120 Sap Street|Shreveport|LA|71104|US 22 | 10000000-0000-0000-0000-000000000021|121 Tonka Trail|Tyler|TX|75799|US 23 | 10000000-0000-0000-0000-000000000022|122 Under Court|Unalakleet|AK|99684|US 24 | 10000000-0000-0000-0000-000000000023|123 Verde Drive|Vero Beach|FL|32960|US 25 | 10000000-0000-0000-0000-000000000024|124 Xanadu Boulevard|Xenia|OH|45385|US 26 | 10000000-0000-0000-0000-000000000025|125 Wiggins Way|Wright|WY|82732|US 27 | 10000000-0000-0000-0000-000000000026|125 Yeti Circle|Yonkers|NY|10701|US 28 | 10000000-0000-0000-0000-000000000027|1284 Zzyzx Road|Zzyzx|CA|92309|US 29 | 10000000-0000-0000-0000-000000000028|1265 Anchor Terrace SW|Atlanta|GA|30311|US 30 | 10000000-0000-0000-0000-000000000029|739 Baylor Ave|Bonita|CA|91902|US 31 | 10000000-0000-0000-0000-000000000030|4619 Crimson Cir N|Colorado Springs|CO|80917|US 32 | 10000000-0000-0000-0000-000000000031|1817 S Barrington Ave|Los Angeles|CA|90025|US 33 | 10000000-0000-0000-0000-000000000032|3440 Topping Rd|Madison|WI|53705|US 34 | 10000000-0000-0000-0000-000000000033|650 Del Prado Drive|Boulder City|NV|89005|US 35 | 10000000-0000-0000-0000-000000000034|650 Del Prado Drive|Boulder City|NV|89005|US -------------------------------------------------------------------------------- /fraud/data/customerAddresses.json: -------------------------------------------------------------------------------- 1 | {"address": {"address":"101 Adams Lane", "postalCode":"99501"}, "customerId": "10000000-0000-0000-0000-000000000001"} 2 | {"address": {"address":"102 Bellevue Blvd", "postalCode":"21201"}, "customerId": "10000000-0000-0000-0000-000000000002"} 3 | {"address": {"address":"103 Charity Court", "postalCode":"45201"}, "customerId": "10000000-0000-0000-0000-000000000003"} 4 | {"address": {"address":"104 Dilbert Drive", "postalCode":"48201"}, "customerId": "10000000-0000-0000-0000-000000000004"} 5 | {"address": {"address":"105 Echo Lane", "postalCode":"79900"}, "customerId": "10000000-0000-0000-0000-000000000005"} 6 | {"address": {"address":"106 Felicity Lane", "postalCode":"33301"}, "customerId": "10000000-0000-0000-0000-000000000006"} 7 | {"address": {"address":"107 George Court", "postalCode":"54301"}, "customerId": "10000000-0000-0000-0000-000000000007"} 8 | {"address": {"address":"108 Harris Avenue", "postalCode":"96801"}, "customerId": "10000000-0000-0000-0000-000000000008"} 9 | {"address": {"address":"109 Iowa Avenue", "postalCode":"46201"}, "customerId": "10000000-0000-0000-0000-000000000009"} 10 | {"address": {"address":"110 Joshua Avenue", "postalCode":"65101"}, "customerId": "10000000-0000-0000-0000-000000000010"} 11 | {"address": {"address":"111 Karma Court", "postalCode":"33040"}, "customerId": "10000000-0000-0000-0000-000000000011"} 12 | {"address": {"address":"112 Leming Lane", "postalCode":"70598"}, "customerId": "10000000-0000-0000-0000-000000000012"} 13 | {"address": {"address":"113 Memphis Parkway", "postalCode":"39301"}, "customerId": "10000000-0000-0000-0000-000000000013"} 14 | {"address": {"address":"102 Bellevue Blvd", "postalCode":"21201"}, "customerId": "10000000-0000-0000-0000-000000000014"} 15 | {"address": {"address":"115 Naples Street", "postalCode":"99641"}, "customerId": "10000000-0000-0000-0000-000000000015"} 16 | {"address": {"address":"116 Ocean Place", "postalCode":"73101"}, "customerId": "10000000-0000-0000-0000-000000000016"} 17 | {"address": {"address":"117 Pelican Place", "postalCode":"19092"}, "customerId": "10000000-0000-0000-0000-000000000017"} 18 | {"address": {"address":"118 Quisenberry Avenue", "postalCode":"11011"}, "customerId": "10000000-0000-0000-0000-000000000018"} 19 | {"address": {"address":"119 Reginald Road", "postalCode":"88201"}, "customerId": "10000000-0000-0000-0000-000000000019"} 20 | {"address": {"address":"120 Sap Street", "postalCode":"71104"}, "customerId": "10000000-0000-0000-0000-000000000020"} 21 | {"address": {"address":"121 Tonka Trail", "postalCode":"75799"}, "customerId": "10000000-0000-0000-0000-000000000021"} 22 | {"address": {"address":"122 Under Court", "postalCode":"99684"}, "customerId": "10000000-0000-0000-0000-000000000022"} 23 | {"address": {"address":"123 Verde Drive", "postalCode":"32960"}, "customerId": "10000000-0000-0000-0000-000000000023"} 24 | {"address": {"address":"124 Xanadu Boulevard", "postalCode":"45385"}, "customerId": "10000000-0000-0000-0000-000000000024"} 25 | {"address": {"address":"125 Wiggins Way", "postalCode":"82732"}, "customerId": "10000000-0000-0000-0000-000000000025"} 26 | {"address": {"address":"125 Yeti Circle", "postalCode":"10701"}, "customerId": "10000000-0000-0000-0000-000000000026"} 27 | {"address": {"address":"1284 Zzyzx Road", "postalCode":"92309"}, "customerId": "10000000-0000-0000-0000-000000000027"} 28 | {"address": {"address":"1265 Anchor Terrace SW", "postalCode":"30311"}, "customerId": "10000000-0000-0000-0000-000000000028"} 29 | {"address": {"address":"739 Baylor Ave", "postalCode":"91902"}, "customerId": "10000000-0000-0000-0000-000000000029"} 30 | {"address": {"address":"4619 Crimson Cir N", "postalCode":"80917"}, "customerId": "10000000-0000-0000-0000-000000000030"} 31 | {"address": {"address":"1817 S Barrington Ave", "postalCode":"90025"}, "customerId": "10000000-0000-0000-0000-000000000031"} 32 | {"address": {"address":"3440 Topping Rd", "postalCode":"53705"}, "customerId": "10000000-0000-0000-0000-000000000032"} 33 | {"address": {"address":"650 Del Prado Drive", "postalCode":"89005"}, "customerId": "10000000-0000-0000-0000-000000000033"} 34 | {"address": {"address":"650 Del Prado Drive", "postalCode":"89005"}, "customerId": "10000000-0000-0000-0000-000000000034"} -------------------------------------------------------------------------------- /fraud/data/customerChargebacks.csv: -------------------------------------------------------------------------------- 1 | customerid|chargebacknumber 2 | 10000000-0000-0000-0000-000000000025|2017033101 3 | 10000000-0000-0000-0000-000000000026|2017063005 4 | 10000000-0000-0000-0000-000000000028|2017060244 -------------------------------------------------------------------------------- /fraud/data/customerOrders.csv: -------------------------------------------------------------------------------- 1 | customerid|orderid 2 | 10000000-0000-0000-0000-000000000001|40000000-0000-0000-0001-000000000001 3 | 10000000-0000-0000-0000-000000000002|40000000-0000-0000-0002-000000000002 4 | 10000000-0000-0000-0000-000000000003|40000000-0000-0000-0003-000000000003 5 | 10000000-0000-0000-0000-000000000025|40000000-0000-0000-0025-000000000004 6 | 10000000-0000-0000-0000-000000000004|40000000-0000-0000-0004-000000000005 7 | 10000000-0000-0000-0000-000000000026|40000000-0000-0000-4021-000000000006 8 | 10000000-0000-0000-0000-000000000027|40000000-0000-0000-0991-000000000008 9 | 10000000-0000-0000-0000-000000000028|40000000-0000-0000-0101-000000000012 10 | 10000000-0000-0000-0000-000000000029|40000000-0000-0000-0018-000000000094 11 | 10000000-0000-0000-0000-000000000030|40000000-0000-0000-0003-000000000188 12 | 10000000-0000-0000-0000-000000000031|40000000-0000-0000-9184-000000000032 13 | 10000000-0000-0000-0000-000000000032|40000000-0000-0000-1225-000000000311 14 | 10000000-0000-0000-0000-000000000033|40000000-0000-0000-9110-000000040001 15 | 10000000-0000-0000-0000-000000000034|40000000-0000-0000-0148-000000000304 -------------------------------------------------------------------------------- /fraud/data/customerSessions.csv: -------------------------------------------------------------------------------- 1 | customerid|sessionid 2 | 10000000-0000-0000-0000-000000000001|20000000-0000-0000-0001-000000000001 3 | 10000000-0000-0000-0000-000000000001|20000000-0000-0000-0001-000000000002 4 | 10000000-0000-0000-0000-000000000001|20000000-0000-0000-0001-000000000003 5 | 10000000-0000-0000-0000-000000000001|20000000-0000-0000-0001-000000000004 6 | 10000000-0000-0000-0000-000000000002|20000000-0000-0000-0002-000000000005 7 | 10000000-0000-0000-0000-000000000014|20000000-0000-0000-0014-000000000006 8 | 10000000-0000-0000-0000-000000000015|20000000-0000-0000-0015-000000000007 9 | 10000000-0000-0000-0000-000000000016|20000000-0000-0000-0016-000000000008 10 | 10000000-0000-0000-0000-000000000017|20000000-0000-0000-0017-000000000009 11 | 10000000-0000-0000-0000-000000000018|20000000-0000-0000-0018-000000000010 12 | 10000000-0000-0000-0000-000000000019|20000000-0000-0000-0019-000000000011 13 | 10000000-0000-0000-0000-000000000020|20000000-0000-0000-0020-000000000012 14 | 10000000-0000-0000-0000-000000000021|20000000-0000-0000-0021-000000000013 15 | 10000000-0000-0000-0000-000000000022|20000000-0000-0000-0022-000000000014 16 | 10000000-0000-0000-0000-000000000023|20000000-0000-0000-0023-000000000015 17 | 10000000-0000-0000-0000-000000000024|20000000-0000-0000-0024-000000000016 18 | 10000000-0000-0000-0000-000000000003|20000000-0000-0000-0003-000000000017 19 | 10000000-0000-0000-0000-000000000025|20000000-0000-0000-0025-000000000018 20 | 10000000-0000-0000-0000-000000000004|20000000-0000-0000-0004-000000000020 21 | 10000000-0000-0000-0000-000000000026|20000000-0000-0000-0000-000000000026 22 | 10000000-0000-0000-0000-000000000026|20000000-0000-0002-0048-000000000082 23 | 10000000-0000-0000-0000-000000000027|20000000-0000-8093-0002-000000000138 24 | 10000000-0000-0000-0000-000000000028|20000000-0000-0040-0009-000000001943 25 | 10000000-0000-0000-0000-000000000028|20000000-0000-0040-0299-000000000334 26 | 10000000-0000-0000-0000-000000000029|20000000-0000-0040-0028-000000003980 27 | 10000000-0000-0000-0000-000000000030|20000000-0000-0040-0099-000000040010 28 | 10000000-0000-0000-0000-000000000031|20000000-0000-0040-0022-000000001334 29 | 10000000-0000-0000-0000-000000000032|20000000-0000-0040-0019-000000000914 30 | 10000000-0000-0000-0000-000000000033|20000000-0000-0040-0012-000000005190 31 | 10000000-0000-0000-0000-000000000034|20000000-0000-0040-0038-000000000310 -------------------------------------------------------------------------------- /fraud/data/customers.csv: -------------------------------------------------------------------------------- 1 | customerid|firstname|lastname|email|phone|createdtime 2 | 10000000-0000-0000-0000-000000000001|Aaron|Atkins|atkinsman@yahoo.com|100-000-0001|2017-04-01T00:00:00.00Z 3 | 10000000-0000-0000-0000-000000000002|Ben|Bailey|ben.bailey22@gmail.com|100-000-0002|2017-04-01T00:00:00.00Z 4 | 10000000-0000-0000-0000-000000000003|Charles|Chardonnay|chardonnay.family@aol.com|100-000-0003|2017-04-01T00:00:00.00Z 5 | 10000000-0000-0000-0000-000000000004|Divya|Divani|divine.divya@gmail.com|100-000-0004|2017-04-01T00:00:00.00Z 6 | 10000000-0000-0000-0000-000000000005|Evelyn|Esther|evelyn44@me.com|100-000-0005|2017-04-01T00:00:00.00Z 7 | 10000000-0000-0000-0000-000000000006|Freddie|Flake|freddie.flake@comcast.net|100-000-0006|2017-04-01T00:00:00.00Z 8 | 10000000-0000-0000-0000-000000000007|Guillaume|Gadot|guillaume.golfer@live.com|100-000-0007|2017-04-01T00:00:00.00Z 9 | 10000000-0000-0000-0000-000000000008|Hari|Hirendra|sunshine.hari@gmail.com|100-000-0008|2017-04-01T00:00:00.00Z 10 | 10000000-0000-0000-0000-000000000009|Ian|Ireland|ian.ireland88@yahoo.com|100-000-0009|2017-04-01T00:00:00.00Z 11 | 10000000-0000-0000-0000-000000000010|John|Jameson|scubaguy12@gmail.com|100-000-0010|2017-04-01T00:00:00.00Z 12 | 10000000-0000-0000-0000-000000000011|Kim|Karlton|kim@karltonfamily.org|100-000-0011|2017-04-01T00:00:00.00Z 13 | 10000000-0000-0000-0000-000000000012|Li|Liang|lliang@qwest.com|100-000-0012|2017-04-01T00:00:00.00Z 14 | 10000000-0000-0000-0000-000000000013|Maria|Manuel|netdragon@yahoo.com|100-000-0013|2017-04-01T00:00:00.00Z 15 | 10000000-0000-0000-0000-000000000014|Julie|Bailey|jules47@aol.com|100-000-0014|2017-03-01T00:00:00.00Z 16 | 10000000-0000-0000-0000-000000000015|Nancy|Nicety|nnicety@sbcglobal.net|100-000-0014|2017-03-01T00:00:00.00Z 17 | 10000000-0000-0000-0000-000000000016|Osirus|O'Sirus|osirus@osirusplumbing.com|100-000-0014|2017-03-01T00:00:00.00Z 18 | 10000000-0000-0000-0000-000000000017|Paul|Pierce|paul.pierce@comcast.net|100-000-0014|2017-03-01T00:00:00.00Z 19 | 10000000-0000-0000-0000-000000000018|Quentin|Quickening|qquickening@empirepublishing.com|100-000-0014|2017-03-01T00:00:00.00Z 20 | 10000000-0000-0000-0000-000000000019|Ruth|Regalo|ruth.regalo48@aol.com|100-000-0014|2017-03-01T00:00:00.00Z 21 | 10000000-0000-0000-0000-000000000020|Sally|Struthers|another.sally84@yahoo.com|100-000-0014|2017-03-01T00:00:00.00Z 22 | 10000000-0000-0000-0000-000000000021|Thomas|Timothy|binaryboy12@gmail.com|100-000-0014|2017-03-01T00:00:00.00Z 23 | 10000000-0000-0000-0000-000000000022|Ulysses|Unilever|ulysses128@gmail.com|100-000-0014|2017-03-01T00:00:00.00Z 24 | 10000000-0000-0000-0000-000000000023|Vera|Verily|dancer.vera@yahoo.com|100-000-0014|2017-03-01T00:00:00.00Z 25 | 10000000-0000-0000-0000-000000000024|Xavier|Xanders|xavier.xanders@gmail.com|100-000-0014|2017-03-01T00:00:00.00Z 26 | 10000000-0000-0000-0000-000000000025|Wanda|Wichita|help.me.wanda@yahoo.com|100-000-0014|2017-01-01T00:00:00.00Z 27 | 10000000-0000-0000-0000-000000000026|Yolanda|Yucutan|yonkers.yolanda@aol.com|100-000-0014|2017-04-01T00:00:00.00Z 28 | 10000000-0000-0000-0000-000000000027|Zach|Zelanko|zzelanko@zzyzx.net|442-425-8528|2017-07-01T00:00:00.00Z 29 | 10000000-0000-0000-0000-000000000028|Andrew|Adelman|atlanta.andrew@yahoo.com|678-412-9880|2017-03-01T00:00:00.00Z 30 | 10000000-0000-0000-0000-000000000029|Bob|Briody|oitsubob@gmail.com|619-212-5946|2017-03-12T00:00:00.00Z 31 | 10000000-0000-0000-0000-000000000030|Carly|Cotell|ccotell@hp.com|719-585-6201|2017-06-23T00:00:00.00Z 32 | 10000000-0000-0000-0000-000000000031|Peter|Laramore|peter.laramore@warnerbros.com|310-420-1642|2017-02-02T00:00:00.00Z 33 | 10000000-0000-0000-0000-000000000032|Phil|Hargrave|phil@familyhargrave.org|608-940-2256|2017-02-12T00:00:00.00Z 34 | 10000000-0000-0000-0000-000000000033|Joe|Banks|volcanojoe@gmail.com|702-294-2722|2017-02-22T00:00:00.00Z 35 | 10000000-0000-0000-0000-000000000034|Joe|Banks|joe.plus.patricia@stanley.com|702-293-3843|2017-03-04T00:00:00.00Z -------------------------------------------------------------------------------- /fraud/data/devices.csv: -------------------------------------------------------------------------------- 1 | deviceid|type|os|osversion 2 | 30000000-0000-0000-0001-000000000001|tablet|ios|10.3.1 3 | 30000000-0000-0000-0002-000000000003|computer|macos|10.12.3 4 | 30000000-0000-0000-0015-000000000004|computer|linux|3.13.0-107-generic 5 | 30000000-0000-0000-0025-000000000005|tablet|amazon|5.3.2.1 6 | 30000000-0000-0000-0004-000000000007|phone|android|7.1.2 7 | 30000000-0000-0000-0122-000000000064|computer|windows|6.3.9600 8 | 30000000-0000-0000-0080-000000008443|computer|macos|10.12.3 9 | 30000000-0000-0000-0080-000000001211|computer|windows|10.0.10240 10 | 30000000-0000-0000-0003-000000002009|computer|windows|10.0.10240 11 | 30000000-0000-0000-0027-000000000187|tablet|ios|10.3.1 12 | 30000000-0000-0000-1997-000000000022|tablet|android|6.0.1 13 | 30000000-0000-0000-0143-000000017483|computer|macos|10.12.4 14 | 30000000-0000-0000-0099-000000000028|tablet|ios|10.3.1 15 | 30000000-0000-0000-0094-000000000048|computer|macos|10.12.3 16 | 30000000-0000-0000-0080-000000000441|phone|android|6.0.1 17 | 30000000-0000-0000-0014-000000000003|computer|windows|10.0.10240 18 | 30000000-0000-0000-0001-000000000002|phone|ios|10.3.1 19 | 30000000-0000-0000-0026-000000000006|phone|android|6.0.1 -------------------------------------------------------------------------------- /fraud/data/orderChargebacks.csv: -------------------------------------------------------------------------------- 1 | orderid|chargebacknumber 2 | 40000000-0000-0000-0025-000000000004|2017033101 3 | 40000000-0000-0000-0101-000000000012|2017060244 4 | 40000000-0000-0000-4021-000000000006|2017063005 -------------------------------------------------------------------------------- /fraud/data/orders.csv: -------------------------------------------------------------------------------- 1 | orderid|createdtime|outcome|creditcardhashed|ipaddress|amount|deviceid 2 | 40000000-0000-0000-0001-000000000001|2017-04-04T00:00:00Z|Approved|5910f4ea0062a0e29afd3dccc741e3ce|111.111.111.1|100.00|30000000-0000-0000-0001-000000000001 3 | 40000000-0000-0000-0002-000000000002|2017-04-01T00:00:00Z|Approved|1e91b7046b7f4df53c18e559fb916afa|111.111.112.1|200.00|30000000-0000-0000-0014-000000000003 4 | 40000000-0000-0000-0003-000000000003|2017-04-01T00:00:00Z|Declined|579b345a68334b88ef15380719c9be3f|111.111.113.1|500.00|30000000-0000-0000-0015-000000000004 5 | 40000000-0000-0000-0025-000000000004|2017-01-01T00:00:00Z|Approved|a1ab1822888276fdb587a16b2dc7b697|111.111.114.1|150.00|30000000-0000-0000-0025-000000000005 6 | 40000000-0000-0000-0004-000000000005|2017-04-01T00:00:00Z|Declined|a1ab1822888276fdb587a16b2dc7b697|111.111.116.1|225.00|30000000-0000-0000-0004-000000000007 7 | 40000000-0000-0000-4021-000000000006|2017-04-13T00:00:00Z|Approved|fa7987fa879c789be65426e979cbd976|111.111.54.1|450.00|30000000-0000-0000-0122-000000000064 8 | 40000000-0000-0000-0991-000000000008|2017-07-01T00:00:00Z|Declined|84290acb9012e890dd8120cabb9013fe|111.111.31.4|99.00|30000000-0000-0000-0122-000000000064 9 | 40000000-0000-0000-0101-000000000012|2017-03-02T00:00:00Z|Approved|89149a89f9890e0cd89089e342523f21|111.111.84.48|121.79|30000000-0000-0000-0080-000000008443 10 | 40000000-0000-0000-0018-000000000094|2017-03-12T00:00:00Z|Approved|09834915789a89bf4839e8002cc24329|111.111.18.71|188.21|30000000-0000-0000-0080-000000001211 11 | 40000000-0000-0000-0003-000000000188|2017-06-12T00:00:00Z|Declined|09834915789a89bf4839e8002cc24329|111.111.4.73|84.19|30000000-0000-0000-0003-000000002009 12 | 40000000-0000-0000-9184-000000000032|2017-02-02T00:00:00Z|Approved|45748214df934e894ce4893f098149aa|111.111.39.63|112.27|30000000-0000-0000-0027-000000000187 13 | 40000000-0000-0000-1225-000000000311|2017-02-12T00:00:00Z|Approved|8c934d8e90238A471039432c8234083f|111.111.72.49|423.42|30000000-0000-0000-0027-000000000187 14 | 40000000-0000-0000-9110-000000040001|2017-02-22T00:00:00Z|Approved|8c934d8e90238A471039432c8234083f|111.111.9.12|203.45|30000000-0000-0000-1997-000000000022 15 | 40000000-0000-0000-0148-000000000304|2017-03-04T00:00:00Z|Declined|994d2438ef9ac9204b489302489bbae2|111.111.18.28|328.18|30000000-0000-0000-0143-000000017483 -------------------------------------------------------------------------------- /fraud/data/sessions.csv: -------------------------------------------------------------------------------- 1 | sessionid|deviceid|ipaddress|createdtime 2 | 20000000-0000-0000-0001-000000000001|30000000-0000-0000-0001-000000000001|111.111.111.1|2017-04-01T00:00:00.00Z 3 | 20000000-0000-0000-0001-000000000002|30000000-0000-0000-0001-000000000001|111.111.111.1|2017-04-02T00:00:00.00Z 4 | 20000000-0000-0000-0001-000000000003|30000000-0000-0000-0001-000000000002|111.111.111.2|2017-04-03T00:00:00.00Z 5 | 20000000-0000-0000-0001-000000000004|30000000-0000-0000-0001-000000000001|111.111.111.1|2017-04-04T00:00:00.00Z 6 | 20000000-0000-0000-0002-000000000005|30000000-0000-0000-0002-000000000003|111.111.112.1|2017-04-01T00:00:00.00Z 7 | 20000000-0000-0000-0014-000000000006|30000000-0000-0000-0014-000000000003|111.111.112.1|2017-03-01T00:00:00.00Z 8 | 20000000-0000-0000-0015-000000000007|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-22T00:00:00.00Z 9 | 20000000-0000-0000-0016-000000000008|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-23T00:00:00.00Z 10 | 20000000-0000-0000-0017-000000000009|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-24T00:00:00.00Z 11 | 20000000-0000-0000-0018-000000000010|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-25T00:00:00.00Z 12 | 20000000-0000-0000-0019-000000000011|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-26T00:00:00.00Z 13 | 20000000-0000-0000-0020-000000000012|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-27T00:00:00.00Z 14 | 20000000-0000-0000-0021-000000000013|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-28T00:00:00.00Z 15 | 20000000-0000-0000-0022-000000000014|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-29T00:00:00.00Z 16 | 20000000-0000-0000-0023-000000000015|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-30T00:00:00.00Z 17 | 20000000-0000-0000-0024-000000000016|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-03-31T00:00:00.00Z 18 | 20000000-0000-0000-0003-000000000017|30000000-0000-0000-0015-000000000004|111.111.113.1|2017-04-01T00:00:00.00Z 19 | 20000000-0000-0000-0025-000000000018|30000000-0000-0000-0025-000000000005|111.111.114.1|2017-01-01T00:00:00.00Z 20 | 20000000-0000-0000-0026-000000000019|30000000-0000-0000-0026-000000000006|111.111.115.1|2017-04-01T00:00:00.00Z 21 | 20000000-0000-0000-0004-000000000020|30000000-0000-0000-0004-000000000007|111.111.116.1|2017-04-01T00:00:00.00Z 22 | 20000000-0000-0000-0000-000000000026|30000000-0000-0000-0099-000000000028|111.111.121.1|2017-04-12T00:00:00.00Z 23 | 20000000-0000-0002-0048-000000000082|30000000-0000-0000-0122-000000000064|111.111.54.1|2017-04-13T00:00:00.00Z 24 | 20000000-0000-8093-0002-000000000138|30000000-0000-0000-0094-000000000048|111.111.31.4|2017-07-01T00:00:00.00Z 25 | 20000000-0000-0040-0009-000000001943|30000000-0000-0000-0080-000000001211|111.111.28.18|2017-03-01T00:00:00.00Z 26 | 20000000-0000-0040-0299-000000000334|30000000-0000-0000-0080-000000008443|111.111.84.48|2017-03-02T00:00:00.00Z 27 | 20000000-0000-0040-0028-000000003980|30000000-0000-0000-0080-000000001211|111.111.18.71|2017-03-12T00:00:00.00Z 28 | 20000000-0000-0040-0099-000000040010|30000000-0000-0000-0080-000000000441|111.111.4.73|2017-06-22T00:00:00.00Z 29 | 20000000-0000-0040-0022-000000001334|30000000-0000-0000-0027-000000000187|111.111.39.63|2017-02-02T00:00:00.00Z 30 | 20000000-0000-0040-0019-000000000914|30000000-0000-0000-0027-000000000187|111.111.72.49|2017-02-12T00:00:00.00Z 31 | 20000000-0000-0040-0012-000000005190|30000000-0000-0000-1997-000000000022|111.111.9.12|2017-02-22T00:00:00.00Z 32 | 20000000-0000-0040-0038-000000000310|30000000-0000-0000-0143-000000017483|111.111.18.28|2017-03-04T00:00:00.00Z -------------------------------------------------------------------------------- /fraud/fraud-mapping.groovy.config: -------------------------------------------------------------------------------- 1 | name: "source", type: String, defaultValue: "", description: "The source type (e.g. file, db) from which the graph data to be loaded." 2 | name: "inputpath", type: String, defaultValue: "", description: "The location of the graph data to be loaded." -------------------------------------------------------------------------------- /fraud/mysql-import-data.sql: -------------------------------------------------------------------------------- 1 | load data local infile '~/repos/graph-examples/fraud/data/customers.csv' 2 | into table fraud.customers 3 | fields terminated by '|' escaped by '' 4 | ignore 1 lines; 5 | 6 | load data local infile '~/repos/graph-examples/fraud/data/customerAddresses.csv' 7 | into table fraud.customer_addresses 8 | fields terminated by '|' escaped by '' 9 | ignore 1 lines; 10 | 11 | load data local infile '~/repos/graph-examples/fraud/data/sessions.csv' 12 | into table fraud.sessions 13 | fields terminated by '|' escaped by '' 14 | ignore 1 lines; 15 | 16 | load data local infile '~/repos/graph-examples/fraud/data/devices.csv' 17 | into table fraud.devices 18 | fields terminated by '|' escaped by '' 19 | ignore 1 lines; 20 | 21 | load data local infile '~/repos/graph-examples/fraud/data/orders.csv' 22 | into table fraud.orders 23 | fields terminated by '|' escaped by '' 24 | ignore 1 lines; 25 | 26 | load data local infile '~/repos/graph-examples/fraud/data/chargebacks.csv' 27 | into table fraud.chargebacks 28 | fields terminated by '|' escaped by '' 29 | ignore 1 lines; 30 | 31 | load data local infile '~/repos/graph-examples/fraud/data/creditCards.csv' 32 | into table fraud.creditcards 33 | fields terminated by '|' escaped by '' 34 | ignore 1 lines; 35 | 36 | load data local infile '~/repos/graph-examples/fraud/data/customerOrders.csv' 37 | into table fraud.customer_orders 38 | fields terminated by '|' escaped by '' 39 | ignore 1 lines; 40 | 41 | load data local infile '~/repos/graph-examples/fraud/data/orderChargebacks.csv' 42 | into table fraud.order_chargebacks 43 | fields terminated by '|' escaped by '' 44 | ignore 1 lines; 45 | 46 | load data local infile '~/repos/graph-examples/fraud/data/customerSessions.csv' 47 | into table fraud.customer_sessions 48 | fields terminated by '|' escaped by '' 49 | ignore 1 lines; 50 | 51 | load data local infile '~/repos/graph-examples/fraud/data/customerChargebacks.csv' 52 | into table fraud.customer_chargebacks 53 | fields terminated by '|' escaped by '' 54 | ignore 1 lines; -------------------------------------------------------------------------------- /fraud/mysql-schema.sql: -------------------------------------------------------------------------------- 1 | drop database if exists fraud; 2 | create database fraud; 3 | use `fraud`; 4 | 5 | create table customers ( 6 | customerid char(36) primary key, 7 | firstname varchar(64), 8 | lastname varchar(64), 9 | email varchar(128), 10 | phone varchar(64), 11 | createdtime timestamp 12 | ); 13 | 14 | create table customer_addresses ( 15 | customerid char(36) primary key, 16 | address varchar(128), 17 | city varchar(64), 18 | state varchar(64), 19 | postalcode varchar(64), 20 | countrycode varchar(64) 21 | ); 22 | 23 | create table sessions ( 24 | sessionid char(36) primary key, 25 | deviceid char(36), 26 | ipaddress varchar(128), 27 | createdtime timestamp 28 | ); 29 | 30 | create table devices ( 31 | deviceid char(36) primary key, 32 | type varchar(64), 33 | os varchar(64), 34 | osversion varchar(64) 35 | ); 36 | 37 | create table orders ( 38 | orderid char(36) primary key, 39 | createdtime timestamp, 40 | outcome varchar(64), 41 | creditcardhashed varchar(64), 42 | ipaddress varchar(128), 43 | amount decimal, 44 | deviceid char(36) 45 | ); 46 | 47 | create table chargebacks ( 48 | chargebacknumber integer primary key, 49 | amount decimal, 50 | createdtime timestamp, 51 | creditcardhashed varchar(64) 52 | ); 53 | 54 | create table creditcards ( 55 | creditcardhashed varchar(64) primary key, 56 | type varchar(64) 57 | ); 58 | 59 | create table customer_orders ( 60 | customerid char(36), 61 | orderid char(36), 62 | primary key (customerid, orderid) 63 | ); 64 | 65 | create table order_chargebacks ( 66 | orderid char(36), 67 | chargebacknumber integer, 68 | primary key (orderid, chargebacknumber) 69 | ); 70 | 71 | create table customer_sessions ( 72 | customerid char(36), 73 | sessionid char(36), 74 | primary key (customerid, sessionid) 75 | ); 76 | 77 | create table customer_chargebacks ( 78 | customerid char(36), 79 | chargebacknumber integer, 80 | primary key(customerid, chargebacknumber) 81 | ); -------------------------------------------------------------------------------- /fraud/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.datastax.fraud 4 | data-import 5 | 1.0-SNAPSHOT 6 | jar 7 | 8 | 6.0.9 9 | 2.11.8 10 | 2.11 11 | 4.0 12 | 4.12 13 | 14 | 15 | 16 | 17 | scala-tools.org 18 | Scala-Tools Maven2 Repository 19 | http://scala-tools.org/repo-releases 20 | 21 | 22 | 23 | 24 | com.datastax.dse 25 | dse-spark-dependencies 26 | ${dse.version} 27 | provided 28 | 29 | 30 | org.apache.directory.api 31 | * 32 | 33 | 34 | 35 | 36 | com.datastax.dse 37 | dse-graph-frames 38 | ${dse.version} 39 | 40 | 41 | 42 | 43 | 44 | DataStax-Repo 45 | https://repo.datastax.com/public-repos/ 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | net.alchim31.maven 55 | scala-maven-plugin 56 | 3.2.2 57 | 58 | 59 | process-sources 60 | 61 | compile 62 | 63 | 64 | 65 | ${project.build.sourceDirectory}/../scala 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-shade-plugin 74 | 2.4.3 75 | 76 | 77 | package 78 | 79 | shade 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /fraud/schema.groovy: -------------------------------------------------------------------------------- 1 | system.graph('fraud').ifNotExists().create() 2 | :remote config alias g fraud.g 3 | 4 | // Property keys 5 | schema.propertyKey('customerid').Uuid().ifNotExists().create() 6 | schema.propertyKey('firstname').Text().ifNotExists().create() 7 | schema.propertyKey('lastname').Text().ifNotExists().create() 8 | schema.propertyKey('email').Text().ifNotExists().create() 9 | schema.propertyKey('address').Text().ifNotExists().create() 10 | schema.propertyKey('city').Text().ifNotExists().create() 11 | schema.propertyKey('state').Text().ifNotExists().create() 12 | schema.propertyKey('postalcode').Text().ifNotExists().create() 13 | schema.propertyKey('countrycode').Text().ifNotExists().create() 14 | schema.propertyKey('phone').Text().ifNotExists().create() 15 | schema.propertyKey('createdtime').Timestamp().ifNotExists().create() 16 | 17 | schema.propertyKey('sessionid').Uuid().ifNotExists().create() 18 | schema.propertyKey('ipaddress').Text().ifNotExists().create() 19 | schema.propertyKey('deviceid').Uuid().ifNotExists().create() 20 | 21 | schema.propertyKey('orderid').Uuid().ifNotExists().create() 22 | schema.propertyKey('outcome').Text().ifNotExists().create() 23 | schema.propertyKey('creditcardhashed').Text().ifNotExists().create() 24 | schema.propertyKey('amount').Decimal().ifNotExists().create() 25 | 26 | schema.propertyKey('chargebacknumber').Int().ifNotExists().create() 27 | 28 | schema.propertyKey('type').Text().ifNotExists().create() 29 | schema.propertyKey('os').Text().ifNotExists().create() 30 | schema.propertyKey('osversion').Text().ifNotExists().create() 31 | 32 | // Vertex labels 33 | schema.vertexLabel('customer').partitionKey('customerid').properties('firstname', 'lastname', 'email', 'phone', 'createdtime').ifNotExists().create() 34 | schema.vertexLabel('address').partitionKey('address', 'postalcode').properties('city', 'state', 'countrycode').ifNotExists().create() 35 | schema.vertexLabel('session').partitionKey('sessionid').properties('ipaddress', 'deviceid', 'createdtime').ifNotExists().create() 36 | schema.vertexLabel('order').partitionKey('orderid').properties('createdtime', 'outcome', 'creditcardhashed', 'ipaddress', 'amount', 'deviceid').ifNotExists().create() 37 | schema.vertexLabel('chargeback').partitionKey('chargebacknumber').properties('createdtime', 'amount', 'creditcardhashed').ifNotExists().create() 38 | schema.vertexLabel('creditCard').partitionKey('creditcardhashed').properties('type').ifNotExists().create() 39 | schema.vertexLabel('device').partitionKey('deviceid').properties('type', 'os', 'osversion').ifNotExists().create() 40 | 41 | // Edge labels 42 | schema.edgeLabel('hasAddress').single().connection('customer', 'address').ifNotExists().create() 43 | schema.edgeLabel('places').single().connection('customer', 'order').ifNotExists().create() 44 | schema.edgeLabel('usesCard').single().connection('order', 'creditCard').ifNotExists().create() 45 | schema.edgeLabel('logsInto').single().connection('customer', 'session').ifNotExists().create() 46 | schema.edgeLabel('chargedWith').single().connection('customer', 'chargeback').ifNotExists().create() 47 | schema.edgeLabel('fromCard').single().connection('chargeback', 'creditCard').ifNotExists().create() 48 | schema.edgeLabel('resultsIn').single().connection('order', 'chargeback').ifNotExists().create() 49 | schema.edgeLabel('using').single().connection('session', 'device').connection('order', 'device').ifNotExists().create() 50 | -------------------------------------------------------------------------------- /killrvideo/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | target/ 3 | .idea/ 4 | [Dd]ebug/ 5 | [Rr]elease/ 6 | [Oo]bj/ 7 | *.suo 8 | *.user 9 | .vscode/ 10 | .vs/ 11 | *nupkg 12 | NuGet.Config 13 | nuget.exe 14 | 15 | -------------------------------------------------------------------------------- /killrvideo/README.md: -------------------------------------------------------------------------------- 1 | # KillrVideo 2 | 3 | The KillrVideo dataset comes from the [DataStax Academy 330 course](https://academy.datastax.com/resources/ds330-datastax-enterprise-graph). It includes metadata about films, users, and ratings. 4 | 5 | Data files: 6 | 7 | * movies.dat (920 records) 8 | movie_id::title::year::duration::country::rating::votes::genres::actors::directors::composers::screenwriters::cinematographers::production_companies 9 | Note: multiple genres, actor, directors, composers, screenwriters, cinematographers, and production_companies are separated by | 10 | * users.dat (1100 records) 11 | user_id::gender::age 12 | * ratings.dat (48094 records) 13 | user_id::movie_id::rating 14 | Note: only subset of user ratings is made available; if aggregation is performed, an average rating (but not the number of votes) will approximately match the rating in movies.dat 15 | * friendship.dat (3500 records) 16 | user_id::friend_user_id 17 | * genres.dat (18 records) 18 | genre_id::genre 19 | * persons.dat (8759 records) 20 | person_id::name 21 | Note: these represent all unique actors, directors, composers, screenwriters, and cinematographers 22 | Note: some non-person exceptions include "Animation" for actors, "Miscellaneous" for composers, "The Beatles" for actors, etc. 23 | 24 | Interesting dataset properties: 25 | 26 | * Users form 4 natural clusters based on movies they like 27 | Users with ids 1-200 (A), 201-700 (B), 701-900 (C), 901-1100 (D) 28 | * Users that belong to the same cluster may exhibit age and/or gender similarities 29 | A: most of age 12-17 30 | B: most of age 18-65 31 | C: most of age 20-40, more males 32 | D: most of age 18-35, more females 33 | * Friendship or "knows" relationships form a small world with 6 degrees of separation 34 | * Clustering coefficient for "knows" relationships is different for each user group 35 | (Largest) C > A and D > B (Smallest) 36 | 37 | ## Loading 38 | 39 | The following steps assumes that there is a running DSE Graph instance in place. First, either load the script in studio or do as the schema script specifies and uncomment the specified lines before executing the script as follows: 40 | 41 | ```text 42 | $ bin/dse gremlin-console -i ../graph-examples/killrvideo/schema.groovy 43 | ``` 44 | 45 | Be sure to properly set the path to the `schema.groovy` file. Now the data can be loaded with the [DSE Graph Loader](https://docs.datastax.com/en/dse/5.1/dse-dev/datastax_enterprise/graph/dgl/dglOverview.html): 46 | 47 | ```text 48 | java -jar target/dse-graph-loader-*-uberjar.jar killrvideo/killrvideo-mapping.groovy -graph killrvideo -preparation false 49 | ``` 50 | 51 | Going back to the open Gremlin Console, it can be quickly validated that the data is loaded and indices are in place: 52 | 53 | ```text 54 | gremlin> g.V().hasLabel('movie').has('title','Young Guns') 55 | ==>v[{~label=movie, community_id=823607168, member_id=475}] 56 | ``` 57 | 58 | 59 | -------------------------------------------------------------------------------- /killrvideo/data/genres.dat: -------------------------------------------------------------------------------- 1 | 1::Action 2 | 2::Adventure 3 | 3::Animation 4 | 4::Comedy 5 | 5::Documentary 6 | 6::Drama 7 | 7::Fantasy 8 | 8::Film-Noir 9 | 9::Horror 10 | 10::Kids 11 | 11::Musical 12 | 12::Mystery 13 | 13::Romance 14 | 14::Sci-Fi 15 | 15::TV Series 16 | 16::Thriller 17 | 17::War 18 | 18::Western 19 | -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KillrVideo", "KillrVideo\KillrVideo.csproj", "{CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|x64.ActiveCfg = Debug|x64 24 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|x64.Build.0 = Debug|x64 25 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|x86.ActiveCfg = Debug|x86 26 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Debug|x86.Build.0 = Debug|x86 27 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|x64.ActiveCfg = Release|x64 30 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|x64.Build.0 = Release|x64 31 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|x86.ActiveCfg = Release|x86 32 | {5558BD66-22AA-44DB-A9A3-B4558FF215EA}.Release|x86.Build.0 = Release|x86 33 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|x64.ActiveCfg = Debug|x64 36 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|x64.Build.0 = Debug|x64 37 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|x86.ActiveCfg = Debug|x86 38 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Debug|x86.Build.0 = Debug|x86 39 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|x64.ActiveCfg = Release|x64 42 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|x64.Build.0 = Release|x64 43 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|x86.ActiveCfg = Release|x86 44 | {CAA4ABB3-A816-4864-A6E9-5AFAE5642FBE}.Release|x86.Build.0 = Release|x86 45 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|x64.ActiveCfg = Debug|x64 48 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|x64.Build.0 = Debug|x64 49 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|x86.ActiveCfg = Debug|x86 50 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Debug|x86.Build.0 = Debug|x86 51 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|x64.ActiveCfg = Release|x64 54 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|x64.Build.0 = Release|x64 55 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|x86.ActiveCfg = Release|x86 56 | {E7C54C5B-6554-4C7A-9CF0-54BEAC8C3718}.Release|x86.Build.0 = Release|x86 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/Dsl/Enrichment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using Gremlin.Net.Process.Traversal; 5 | using Gremlin.Net.Structure; 6 | 7 | using static KillrVideo.Dsl.Kv; 8 | 9 | namespace KillrVideo.Dsl 10 | { 11 | /// 12 | /// Provides for pre-built data enrichment options for the enrich(Enrichment...) step. These options will 13 | /// include extra information about the Vertex> when output from that step. Note that the enrichment 14 | /// examples presented here are examples to demonstrate this concept. The primary lesson here is to show how one might 15 | /// merge map results as part of a DSL. These enrichment options may not be suitable for traversals in production systems 16 | /// as counting all edges might add an unreasonable amount of time to an otherwise fast traversal. 17 | /// 18 | public class Enrichment 19 | { 20 | private List projectedKeys; 21 | private List> traversals; 22 | 23 | private Enrichment(string projectedKeys, GraphTraversal traversal) : 24 | this(new List() { projectedKeys }, new List>() {traversal }) 25 | { 26 | } 27 | 28 | private Enrichment(List projectedKeys, List> traversals) 29 | { 30 | this.projectedKeys = projectedKeys; 31 | this.traversals = traversals; 32 | } 33 | 34 | public List> GetTraversals() 35 | { 36 | return traversals; 37 | } 38 | 39 | public List GetProjectedKeys() 40 | { 41 | return projectedKeys; 42 | } 43 | 44 | /// 45 | /// Include the Vertex itself as a value in the enriched output which might be helpful if additional 46 | /// traversing on that element is required. 47 | /// 48 | public static Enrichment Vertex() 49 | { 50 | return new Enrichment(KeyVertex, __.Identity()); 51 | } 52 | 53 | /// 54 | /// The number of incoming edges on the Vertex. 55 | /// 56 | public static Enrichment InDegree() 57 | { 58 | return new Enrichment(KeyInDegree, __.Map(__.InE().Count())); 59 | } 60 | 61 | 62 | /// 63 | /// The number of outgoing edges on the Vertex. 64 | /// 65 | public static Enrichment OutDegree() 66 | { 67 | return new Enrichment(KeyOutDegree, __.Map(__.OutE().Count())); 68 | } 69 | 70 | /// 71 | /// The total number of in and out edges on the Vertex. 72 | /// 73 | public static Enrichment Degree() 74 | { 75 | return new Enrichment(KeyDegree, __.Map(__.BothE().Count())); 76 | } 77 | 78 | /// 79 | /// Calculates the edge label distribution for the Vertex>. 80 | /// 81 | public static Enrichment Distribution() 82 | { 83 | return new Enrichment(KeyDistribution, __.Map(__.BothE().GroupCount().By(T.Label))); 84 | } 85 | 86 | /// 87 | /// Chooses the keys to include in the output. 88 | /// 89 | public static Enrichment Keys(params string[] keys) 90 | { 91 | var valueTraversals = keys.Select(k => __.Values(k)).ToList(); 92 | return new Enrichment(keys.ToList(), valueTraversals); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/Dsl/Genre.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace KillrVideo.Dsl 5 | { 6 | /// 7 | /// The available "genre" vertex types in the KillrVideo dataset. 8 | /// 9 | public enum Genre 10 | { 11 | Action, 12 | Adventure, 13 | Animation, 14 | Comedy, 15 | Documentary, 16 | Drama, 17 | Fantasy, 18 | FilmNoir, 19 | Horror, 20 | Kids, 21 | Musical, 22 | Mystery, 23 | Romance, 24 | SciFi, 25 | TvSeries, 26 | Thriller, 27 | War, 28 | Western 29 | } 30 | 31 | public static class GenreLookup 32 | { 33 | public static readonly Dictionary Names = new Dictionary 34 | { 35 | {Genre.Action, "Action"}, 36 | {Genre.Adventure, "Adventure"}, 37 | {Genre.Animation, "Animation"}, 38 | {Genre.Comedy, "Comedy"}, 39 | {Genre.Documentary, "Documentary"}, 40 | {Genre.Drama, "Drama"}, 41 | {Genre.Fantasy, "Fantasy"}, 42 | {Genre.FilmNoir, "Film-Noir"}, 43 | {Genre.Horror, "Horror"}, 44 | {Genre.Kids, "Kids"}, 45 | {Genre.Musical, "Musical"}, 46 | {Genre.Mystery, "Mystery"}, 47 | {Genre.Romance, "Romance"}, 48 | {Genre.SciFi, "Sci-Fi"}, 49 | {Genre.TvSeries, "TV Series"}, 50 | {Genre.Thriller, "Thriller"}, 51 | {Genre.War, "War"}, 52 | {Genre.Western, "Western"} 53 | }; 54 | } 55 | } -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/Dsl/Kv.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KillrVideo.Dsl 4 | { 5 | /// 6 | /// String tokens for graph element lables and property keys. 7 | /// 8 | public static class Kv 9 | { 10 | public const String VertexMovie = "movie"; 11 | public const String VertexPerson = "person"; 12 | public const String VertexUser = "user"; 13 | public const String VertexGenre = "genre"; 14 | 15 | public const String EdgeActor = "actor"; 16 | public const String EdgeRated = "rated"; 17 | public const String EdgeBelongsTo = "belongsTo"; 18 | 19 | public const String KeyAge = "age"; 20 | public const String KeyCountry = "country"; 21 | public const String KeyDegree = "_degree"; 22 | public const String KeyDuration = "duration"; 23 | public const String KeyInDegree = "_inDegree"; 24 | public const String KeyMovieId = "movieId"; 25 | public const String KeyName = "name"; 26 | public const String KeyOutDegree = "_outDegree"; 27 | public const String KeyDistribution = "_distribution"; 28 | public const String KeyPersonId = "personId"; 29 | public const String KeyProduction = "production"; 30 | public const String KeyRating = "rating"; 31 | public const String KeyTitle = "title"; 32 | public const String KeyUserId = "userId"; 33 | public const String KeyVertex = "_vertex"; 34 | public const String KeyYear = "year"; 35 | } 36 | } -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/Dsl/Recommender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Gremlin.Net.Process.Traversal; 4 | using Gremlin.Net.Structure; 5 | 6 | using static KillrVideo.Dsl.Kv; 7 | 8 | namespace KillrVideo.Dsl 9 | { 10 | /// 11 | /// Provides for pre-built "sampling" settings to the recommend(int, int, Recommender, Traversal) 12 | /// step. The sampling options help determine the nature of the initial set of movies to recommend, by limiting the 13 | /// number of actors used from highly rated movies of the user who is target for the recommendation. 14 | /// 15 | public enum Recommender 16 | { 17 | SmallSample, 18 | LargeSample, 19 | Fifty50Sample, 20 | TimedSample, 21 | All 22 | } 23 | 24 | public static class RecommenderLookup 25 | { 26 | public static readonly Dictionary>> Traversals = new Dictionary>> 27 | { 28 | {Recommender.SmallSample, __.OutE(EdgeActor).Sample(3).InV().Fold()}, 29 | {Recommender.LargeSample, __.OutE(EdgeActor).Sample(10).InV().Fold()}, 30 | {Recommender.Fifty50Sample, __.OutE(EdgeActor).Coin(0.5).InV().Fold()}, 31 | {Recommender.TimedSample, __.OutE(EdgeActor).TimeLimit(250).InV().Fold()}, 32 | {Recommender.All, __.OutE(EdgeActor).InV().Fold()} 33 | }; 34 | } 35 | } -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/Dsl/__KillrVideo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Gremlin.Net.Process.Traversal; 4 | using Gremlin.Net.Structure; 5 | 6 | using static Gremlin.Net.Process.Traversal.P; 7 | using static KillrVideo.Dsl.Kv; 8 | 9 | namespace KillrVideo.Dsl 10 | { 11 | /// 12 | /// Spawns anonymous traversal instances for the DSL. 13 | /// 14 | public static class __KillrVideo 15 | { 16 | /// 17 | /// Traverses from a "movie" to an "person" over the "actor" edge. 18 | /// 19 | public static GraphTraversal Actors() 20 | { 21 | return __.Out(EdgeActor).HasLabel(VertexPerson); 22 | } 23 | 24 | /// 25 | /// Gets or creates a "person". 26 | /// 27 | /// This step first checks for existence of a person given their identifier. If it exists then the person is 28 | /// returned and their "name" property updated. It is not possible to change the person's identifier once it is 29 | /// assigned (at least as defined by this DSL). If the person does not exist then a new person vertex is added 30 | /// with the specified identifier and name. 31 | /// 32 | public static GraphTraversal Person(string personId, string name) 33 | { 34 | if (string.IsNullOrEmpty(personId)) throw new ArgumentException("The personId must not be null or empty"); 35 | if (string.IsNullOrEmpty(name)) throw new ArgumentException("The name of the person must not be null or empty"); 36 | 37 | return __.Coalesce(__.V().Has(VertexPerson, KeyPersonId, personId), 38 | __.AddV(VertexPerson).Property(KeyPersonId, personId)). 39 | Property(KeyName, name); 40 | } 41 | 42 | /// 43 | /// Assumes a "movie" vertex and traverses to a "genre" vertex with a filter on the name of the genre. This step is meant 44 | /// to be used as part of a filter() step for movies. 45 | /// 46 | public static GraphTraversal Genre(Genre genre, params Genre[] additionalGenres) 47 | { 48 | var genres = new List(); 49 | genres.Add(GenreLookup.Names[genre]); 50 | foreach(Genre current in additionalGenres) 51 | { 52 | genres.Add(GenreLookup.Names[current]); 53 | } 54 | 55 | if (genres.Count < 1) 56 | throw new ArgumentException("There must be at least one genre option provided"); 57 | 58 | if (genres.Count == 1) 59 | return __.Out(EdgeBelongsTo).Map(__.Identity()).Has(KeyName, genres[0]); 60 | else 61 | return __.Out(EdgeBelongsTo).Map(__.Identity()).Has(KeyName, Within(genres)); 62 | } 63 | 64 | /// 65 | /// Gets or creates a "actor". 66 | /// 67 | /// In this schema, an actor is a "person" vertex with an incoming "actor" edge from a "movie" vertex. This step 68 | /// therefore assumes that the incoming stream is a "movie" vertex and actors will be attached to that. This step 69 | /// checks for existence of the "actor" edge first before adding and if found will return the existing one. It 70 | /// further ensures the existence of the "person" vertex as provided by the person(). 71 | /// step. 72 | /// 73 | public static GraphTraversal Actor(string personId, string name) 74 | { 75 | // no validation here as it would just duplicate what is happening in person(). 76 | // 77 | // as mentioned in the javadocs this step assumes an incoming "movie" vertex. it is immediately labelled as 78 | // "^movie". the addition of the caret prefix has no meaning except to provide for a unique labelling space 79 | // within the DSL itself. 80 | 81 | return __.As("^movie"). 82 | Coalesce(__KillrVideo.Actors().Has(VertexPerson, personId), 83 | __KillrVideo.Person(personId, name).AddE(EdgeActor).From("^movie").InV()); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/KillrVideo/KillrVideo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp1.0 5 | portable 6 | KillrVideo 7 | KillrVideo 8 | 1.0.4 9 | Exe 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /killrvideo/dsl/dotnet/README.asciidoc: -------------------------------------------------------------------------------- 1 | == KillrVideo DSL 2 | 3 | This is a .NET starter project that shows how to build a Domain Specific Language (DSL) for 4 | link:http://tinkerpop.apache.org/[Apache TinkerPop's] Gremlin graph traversal language. 5 | link:http://tinkerpop.apache.org/docs/current/reference/#dsl[Gremlin DSLs] provide a way to extend the graph language 6 | with new steps that can help reduce complexity of Gremlin code. 7 | 8 | === Prerequisites 9 | 10 | * dotnet core 1.0.4 11 | * A running instance of link:https://www.datastax.com/products/datastax-enterprise-graph[DSE Graph] 12 | ** Load the `graph-examples/killrvideo` data as specified in the link:https://github.com/datastax/graph-examples/blob/master/killrvideo/README.md[README] 13 | 14 | === Building and Running 15 | 16 | [source,text] 17 | dotnet build 18 | 19 | There is a small application that runs serveral traversals using the defined DSL and outputs the results to the 20 | console. It can be executed with: 21 | 22 | [source,text] 23 | dotnet KillrVideo/bin/Debug/netcoreapp1.0/KillrVideo.dll -------------------------------------------------------------------------------- /killrvideo/dsl/java/README.asciidoc: -------------------------------------------------------------------------------- 1 | == KillrVideo DSL 2 | 3 | This is a Java starter project that shows how to build a Domain Specific Language (DSL) for 4 | link:http://tinkerpop.apache.org/[Apache TinkerPop's] Gremlin graph traversal language. 5 | link:http://tinkerpop.apache.org/docs/current/reference/#dsl[Gremlin DSLs] provide a way to extend the graph language 6 | with new steps that can help reduce complexity of Gremlin code. 7 | 8 | The structure for this project was generated by the Apache TinkerPop 9 | link:http://tinkerpop.apache.org/docs/current/reference/#gremlin-archetypes[Maven archetype for DSLs]. To use this 10 | archetype to get started execute the following command with Maven: 11 | 12 | ```text 13 | mvn archetype:generate -DarchetypeGroupId=org.apache.tinkerpop -DarchetypeArtifactId=gremlin-archetype-dsl -DarchetypeVersion=3.2.5 -DgroupId=com.my -DartifactId=app -Dversion=0.1 -DinteractiveMode=false 14 | ``` 15 | 16 | === Prerequisites 17 | 18 | * Java 8 Update 40+ 19 | * link:https://maven.apache.org/[Maven 3.x] 20 | * A running instance of link:https://www.datastax.com/products/datastax-enterprise-graph[DSE Graph] 21 | ** Load the `graph-examples/killrvideo` data as specified in the link:https://github.com/datastax/graph-examples/blob/master/killrvideo/README.md[README] 22 | 23 | === Building and Running 24 | 25 | [source,text] 26 | mvn clean install 27 | 28 | There is a small application that runs serveral traversals using the defined DSL and outputs the results to the 29 | console. It can be executed through Maven with: 30 | 31 | [source,text] 32 | mvn exec:java -Dexec.mainClass="com.killrvideo.KillrVideoApp" 33 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | com.killrvideo 6 | killrvideo-dsl 7 | 0.1.0-SNAPSHOT 8 | 9 | KillrVideo Graph DSL 10 | 11 | jar 12 | 13 | UTF-8 14 | 15 | 16 | 17 | com.datastax.dse 18 | dse-java-driver-graph 19 | 1.4.0 20 | 21 | 22 | org.slf4j 23 | slf4j-log4j12 24 | 1.7.21 25 | 26 | 27 | junit 28 | junit 29 | 4.12 30 | test 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-compiler-plugin 39 | 3.3 40 | 41 | 1.8 42 | 1.8 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/src/main/java/com/killrvideo/Enrichment.java: -------------------------------------------------------------------------------- 1 | package com.killrvideo; 2 | 3 | import org.apache.tinkerpop.gremlin.process.traversal.Traversal; 4 | import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; 5 | import org.apache.tinkerpop.gremlin.structure.T; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.stream.Collectors; 12 | import java.util.stream.Stream; 13 | 14 | /** 15 | * Provides for pre-built data enrichment options for the {@link KillrVideoTraversalDsl#enrich(Enrichment...)} 16 | * step. These options will include extra information about the {@code Vertex} when output from that step. Note that 17 | * the enrichment examples presented here are examples to demonstrate this concept. The primary lesson here is to show 18 | * how one might merge map results as part of a DSL.These enrichment options may not be suitable for traversals in 19 | * production systems as counting all edges might add an unreasonable amount of time to an otherwise fast traversal. 20 | */ 21 | public class Enrichment { 22 | 23 | private List projectedKey; 24 | 25 | private List traversals; 26 | 27 | private Enrichment(String projectedKeys, GraphTraversal... traversals) { 28 | this(Collections.singletonList(projectedKeys), traversals); 29 | } 30 | 31 | private Enrichment(List projectedKeys, GraphTraversal... traversals) { 32 | this(projectedKeys, Stream.of(traversals).collect(Collectors.toList())); 33 | } 34 | 35 | private Enrichment(List projectedKeys, List traversals) { 36 | if (projectedKeys.size() != traversals.size()) 37 | throw new IllegalArgumentException("projectedKeys and traversals arguments must have an equal number of elements"); 38 | 39 | this.projectedKey = projectedKeys; 40 | this.traversals = traversals; 41 | } 42 | 43 | /** 44 | * Include the {@code Vertex} itself as a value in the enriched output which might be helpful if additional 45 | * traversing on that element is required. 46 | */ 47 | public static Enrichment vertex() { 48 | return new Enrichment(KV.KEY_VERTEX, __.identity()); 49 | } 50 | 51 | /** 52 | * The number of incoming edges on the {@code Vertex}. 53 | */ 54 | public static Enrichment inDegree() { 55 | return new Enrichment(KV.KEY_IN_DEGREE, __.inE().count()); 56 | } 57 | 58 | /** 59 | * The number of outgoing edges on the {@code Vertex}. 60 | */ 61 | public static Enrichment outDegree() { 62 | return new Enrichment(KV.KEY_OUT_DEGREE, __.outE().count()); 63 | } 64 | 65 | /** 66 | * The total number of in and out edges on the {@code Vertex}. 67 | */ 68 | public static Enrichment degree() { 69 | return new Enrichment(KV.KEY_DEGREE, __.bothE().count()); 70 | } 71 | 72 | /** 73 | * Calculates the edge label distribution for the {@code Vertex}. 74 | */ 75 | public static Enrichment distribution() { 76 | return new Enrichment(KV.KEY_DISTRIBUTION, __.bothE().groupCount().by(T.label)); 77 | } 78 | 79 | /** 80 | * Chooses the keys to include in the output. 81 | */ 82 | public static Enrichment keys(String... propertyKeys) { 83 | List projectTraversals = Stream.of(propertyKeys).map(__::values).collect(Collectors.toList()); 84 | return new Enrichment(Arrays.asList(propertyKeys), projectTraversals); 85 | } 86 | 87 | public List getProjectedKey() { 88 | return projectedKey; 89 | } 90 | 91 | public List getTraversals() { 92 | return traversals.stream().map(t -> t.asAdmin().clone()).collect(Collectors.toList()); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/src/main/java/com/killrvideo/Genre.java: -------------------------------------------------------------------------------- 1 | package com.killrvideo; 2 | 3 | /** 4 | * The available "genre" vertex types in the KillrVideo dataset. 5 | */ 6 | public enum Genre { 7 | 8 | ACTION("Action"), 9 | ADVENTURE("Adventure"), 10 | ANIMATION("Animation"), 11 | COMEDY("Comedy"), 12 | DOCUMENTARY("Documentary"), 13 | DRAMA("Drama"), 14 | FANTASY("Fantasy"), 15 | FILM_NOIR("Film-Noir"), 16 | HORROR("Horror"), 17 | KIDS("Kids"), 18 | MUSICAL("Musical"), 19 | MYSTERY("Mystery"), 20 | ROMANCE("Romance"), 21 | SCI_FI("Sci-Fi"), 22 | TV_SERIES("TV Series"), 23 | THRILLER("Thriller"), 24 | WAR("War"), 25 | WESTERN("Western"); 26 | 27 | private String name; 28 | 29 | Genre(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/src/main/java/com/killrvideo/KV.java: -------------------------------------------------------------------------------- 1 | package com.killrvideo; 2 | 3 | /** 4 | * String tokens for graph element lables and property keys. 5 | */ 6 | public class KV { 7 | 8 | public static final String VERTEX_MOVIE = "movie"; 9 | public static final String VERTEX_PERSON = "person"; 10 | public static final String VERTEX_USER = "user"; 11 | public static final String VERTEX_GENRE = "genre"; 12 | 13 | public static final String EDGE_ACTOR = "actor"; 14 | public static final String EDGE_RATED = "rated"; 15 | public static final String EDGE_BELONGS_TO = "belongsTo"; 16 | 17 | public static final String KEY_AGE = "age"; 18 | public static final String KEY_COUNTRY = "country"; 19 | public static final String KEY_DEGREE = "_degree"; 20 | public static final String KEY_DISTRIBUTION = "_distribution"; 21 | public static final String KEY_DURATION = "duration"; 22 | public static final String KEY_IN_DEGREE = "_inDegree"; 23 | public static final String KEY_MOVIE_ID = "movieId"; 24 | public static final String KEY_NAME = "name"; 25 | public static final String KEY_OUT_DEGREE = "_outDegree"; 26 | public static final String KEY_PERSON_ID = "personId"; 27 | public static final String KEY_PRODUCTION = "production"; 28 | public static final String KEY_RATING = "rating"; 29 | public static final String KEY_TITLE = "title"; 30 | public static final String KEY_USER_ID = "userId"; 31 | public static final String KEY_VERTEX = "_vertex"; 32 | public static final String KEY_YEAR = "year"; 33 | } 34 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/src/main/java/com/killrvideo/Recommender.java: -------------------------------------------------------------------------------- 1 | package com.killrvideo; 2 | 3 | import org.apache.tinkerpop.gremlin.process.traversal.Traversal; 4 | 5 | import static com.killrvideo.KV.EDGE_ACTOR; 6 | 7 | /** 8 | * Provides for pre-built "sampling" settings to the {@link KillrVideoTraversalDsl#recommend(int, int, Recommender, Traversal)} 9 | * step. The sampling options help determine the nature of the initial set of movies to recommend, by limiting the 10 | * number of actors used from highly rated movies of the user who is target for the recommendation. 11 | */ 12 | public enum Recommender { 13 | 14 | /** 15 | * Sample three actors. 16 | */ 17 | SMALL_SAMPLE(__.outE(EDGE_ACTOR).sample(3).inV().fold()), 18 | 19 | /** 20 | * Sample ten actors. 21 | */ 22 | LARGE_SAMPLE(__.outE(EDGE_ACTOR).sample(10).inV().fold()), 23 | 24 | /** 25 | * Iterate all actors taking roughly 50% of them. 26 | */ 27 | FIFTY_50_SAMPLE(__.outE(EDGE_ACTOR).coin(0.5d).inV().fold()), 28 | 29 | /** 30 | * For each rated movie take actors for 250ms. 31 | */ 32 | TIMED_SAMPLE(__.outE(EDGE_ACTOR).timeLimit(250).inV().fold()), 33 | 34 | /** 35 | * Do not sample and use all the actors. 36 | */ 37 | ALL(__.outE(EDGE_ACTOR).inV().fold()); 38 | 39 | private Traversal t; 40 | 41 | Recommender(Traversal t) { 42 | this.t = t; 43 | } 44 | 45 | public Traversal getTraversal() { 46 | return t.asAdmin().clone(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /killrvideo/dsl/java/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Set root logger level to DEBUG and its only appender to A1. 2 | log4j.rootLogger=ERROR, A1 3 | 4 | # A1 is set to be a ConsoleAppender. 5 | log4j.appender.A1=org.apache.log4j.ConsoleAppender 6 | 7 | # A1 uses PatternLayout. 8 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout 9 | log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n -------------------------------------------------------------------------------- /killrvideo/dsl/python/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | env 3 | *.pyc 4 | -------------------------------------------------------------------------------- /killrvideo/dsl/python/README.asciidoc: -------------------------------------------------------------------------------- 1 | == KillrVideo DSL 2 | 3 | This is a Python starter project that shows how to build a Domain Specific Language (DSL) for 4 | link:http://tinkerpop.apache.org/[Apache TinkerPop's] Gremlin graph traversal language. 5 | link:http://tinkerpop.apache.org/docs/current/reference/#dsl[Gremlin DSLs] provide a way to extend the graph language 6 | with new steps that can help reduce complexity of Gremlin code. 7 | 8 | === Prerequisites 9 | 10 | * Python 2.7+ 11 | * pip 12 | * A running instance of link:https://www.datastax.com/products/datastax-enterprise-graph[DSE Graph] 13 | ** Load the `graph-examples/killrvideo` data as specified in the link:https://github.com/datastax/graph-examples/blob/master/killrvideo/README.md[README] 14 | 15 | === Building and Running 16 | 17 | There is a small application that runs several traversals using the defined DSL and outputs the results to the 18 | console. It can be executed as follows: 19 | 20 | [source,text] 21 | pip install dse-graph 22 | python app.py 23 | -------------------------------------------------------------------------------- /killrvideo/dsl/python/app.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from killrvideo_dsl.dsl import KillrVideoTraversalSource, __, Recommender, Enrichment 3 | from killrvideo_dsl.kv import * 4 | from killrvideo_dsl.genre import Genre 5 | from gremlin_python.structure.graph import Graph 6 | from dse.cluster import Cluster 7 | from dse_graph import DSESessionRemoteGraphConnection 8 | 9 | COMEDY = Genre.COMEDY 10 | in_degree = Enrichment.in_degree 11 | out_degree = Enrichment.out_degree 12 | keys = Enrichment.keys 13 | genre = __.genre 14 | actor = __.actor 15 | 16 | 17 | def print_header(title, subtitle=""): 18 | print() 19 | t = "* " + title 20 | print(t) 21 | st = "" 22 | if subtitle: 23 | st = "[" + subtitle + "]" 24 | print(st) 25 | 26 | line = "-" * max(len(st), len(t)) 27 | print(line) 28 | 29 | 30 | c = Cluster() 31 | session = c.connect() 32 | 33 | # initialize the TraversalSource for the DSL using the DSE Python Driver 34 | # https://github.com/datastax/python-dse-driver 35 | killr = Graph().traversal(KillrVideoTraversalSource).withRemote(DSESessionRemoteGraphConnection(session, "killrvideo")) 36 | 37 | print_header("Actors for Young Guns", "killr.movies('Young Guns').actors().values('name')") 38 | for n in killr.movies("Young Guns").actors().values("name").toList(): 39 | print(n) 40 | 41 | print_header("Ratings Distribution by Age for Young Guns", "killr.movies('Young Guns').ratings().distribution_for_ages(18, 40)") 42 | ratingsByAge = killr.movies("Young Guns").ratings().distribution_for_ages(18, 40).next() 43 | print(ratingsByAge) 44 | 45 | print_header("Failed Validation", "killr.movies('Young Guns').ratings().distribution_for_ages(17,40)") 46 | try: 47 | killr.movies("Young Guns").ratings().distribution_for_ages(17, 40).next() 48 | except ValueError as ve: 49 | print(ve.args) 50 | 51 | print_header("Five Recommendations for u460", "killr.users('u460').recommend(5, 7).values(KEY_TITLE)") 52 | for r in killr.users("u460").recommend(5, 7).values(KEY_TITLE).toList(): 53 | print(r) 54 | 55 | print_header("Five Recommendations for u460 that are comedies", "killr.users('u460').recommend(5, 7, genre(COMEDY)).values(KEY_TITLE)") 56 | for r in killr.users("u460").recommend(5, 7, genre(COMEDY)).values(KEY_TITLE).toList(): 57 | print(r) 58 | 59 | print_header("Five Recommendations for u460 that use larger actor sampling and are comedies", "killr.users('u460').recommend(5, 7, genre(COMEDY), LARGE_SAMPLE).values(KEY_TITLE)") 60 | for r in killr.users("u460").recommend(5, 7, genre(COMEDY), Recommender.LARGE_SAMPLE).values(KEY_TITLE).toList(): 61 | print(r) 62 | 63 | print_header("Include some additional graph statistics about Young Guns", "killr.movies('Young Guns').enrich(True, keys(KEY_TITLE, KEY_YEAR), in_degree(), out_degree())") 64 | for r in killr.movies("Young Guns").enrich(True, keys(KEY_TITLE, KEY_YEAR), in_degree(), out_degree()).toList(): 65 | print(r) 66 | 67 | print_header("Insert/update movie and actors for that movie", "killr.movie('m100000', 'Manos: The Hands of Fate',...).actor(...)") 68 | (killr.movie("m100000", "Manos: The Hands of Fate", 1966, 70, "USA", "Sun City Films"). 69 | ensure(actor("p1000000", "Tom Neyman")). 70 | ensure(actor("p1000001", "John Reynolds")). 71 | ensure(actor("p1000002", "Diane Mahree")).iterate()) 72 | print("Updated 'Manos: The Hands of Fate'") 73 | 74 | print_header("Get the actors for the newly added movie", "killr.movies('Manos: The Hands of Fate').actors().values('name')") 75 | for n in killr.movies("Manos: The Hands of Fate").actors().values("name").toList(): 76 | print(n) 77 | -------------------------------------------------------------------------------- /killrvideo/dsl/python/killrvideo_dsl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/killrvideo/dsl/python/killrvideo_dsl/__init__.py -------------------------------------------------------------------------------- /killrvideo/dsl/python/killrvideo_dsl/genre.py: -------------------------------------------------------------------------------- 1 | from aenum import Enum 2 | 3 | 4 | class Genre(Enum): 5 | """The available genres of movies in the KillrVideo dataset""" 6 | 7 | ACTION = "Action" 8 | ADVENTURE = "Adventure" 9 | ANIMATION = "Animation" 10 | COMEDY = "Comedy" 11 | DOCUMENTARY = "Documentary" 12 | DRAMA = "Drama" 13 | FANTASY = "Fantasy" 14 | FILM_NOIR = "Film-Noir" 15 | HORROR = "Horror" 16 | KIDS = "Kids" 17 | MUSICAL = "Musical" 18 | MYSTERY = "Mystery" 19 | ROMANCE = "Romance" 20 | SCI_FI = "Sci-Fi" 21 | TV_SERIES = "TV Series" 22 | THRILLER = "Thriller" 23 | WAR = "War" 24 | WESTERN = "Western" 25 | -------------------------------------------------------------------------------- /killrvideo/dsl/python/killrvideo_dsl/kv.py: -------------------------------------------------------------------------------- 1 | VERTEX_MOVIE = 'movie' 2 | VERTEX_PERSON = 'person' 3 | VERTEX_USER = 'user' 4 | VERTEX_GENRE = 'genre' 5 | 6 | EDGE_ACTOR = 'actor' 7 | EDGE_RATED = 'rated' 8 | EDGE_BELONGS_TO = "belongsTo" 9 | EDGE_KNOWS = "knows" 10 | 11 | KEY_AGE = 'age' 12 | KEY_COUNTRY = 'country' 13 | KEY_DEGREE = '_degree' 14 | KEY_DISTRIBUTION = '_distribution' 15 | KEY_DURATION = 'duration' 16 | KEY_IN_DEGREE = '_inDegree' 17 | KEY_MOVIE_ID = 'movieId' 18 | KEY_NAME = 'name' 19 | KEY_OUT_DEGREE = '_outDegree' 20 | KEY_PERSON_ID = 'personId' 21 | KEY_PRODUCTION = 'production' 22 | KEY_RATING = 'rating' 23 | KEY_TITLE = 'title' 24 | KEY_USER_ID = 'userId' 25 | KEY_VERTEX = '_vertex' 26 | KEY_YEAR = 'year' 27 | -------------------------------------------------------------------------------- /killrvideo/dsl/python/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name='killrvideo_dsl', 5 | version='0.1.0', 6 | packages=['killrvideo_dsl'], 7 | url='https://killrvideo.github.io/', 8 | description='KillrVideo DSL', 9 | install_requires=[ 10 | 'aenum', 11 | 'dse-graph', 12 | 'gremlinpython' 13 | ], 14 | classifiers=[ 15 | "Intended Audience :: Developers", 16 | "Natural Language :: English", 17 | "Programming Language :: Python :: 2.7", 18 | "Programming Language :: Python :: 3.4", 19 | "Programming Language :: Python :: 3.5", 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /killrvideo/killrvideo-mapping.groovy.config: -------------------------------------------------------------------------------- 1 | name: "inputpath", type: String, defaultValue: "", description: "The location of the graph data to be loaded." 2 | -------------------------------------------------------------------------------- /killrvideo/schema.groovy: -------------------------------------------------------------------------------- 1 | // Either create the graph in studio and add the following in a cell 2 | // or uncomment and run the following with the gremlin console 3 | /* 4 | :remote config alias reset 5 | system.graph("killrvideo").drop() 6 | system.graph("killrvideo").ifNotExists().create() 7 | :remote config alias g killrvideo.g 8 | :remote config timeout max 9 | */ 10 | 11 | // Define properties 12 | schema.propertyKey("genreId").Text().create(); 13 | schema.propertyKey("personId").Text().create(); 14 | schema.propertyKey("userId").Text().create(); 15 | schema.propertyKey("movieId").Text().create(); 16 | schema.propertyKey("name").Text().create(); 17 | schema.propertyKey("age").Int().create(); 18 | schema.propertyKey("gender").Text().create(); 19 | schema.propertyKey("title").Text().create(); 20 | schema.propertyKey("year").Int().create(); 21 | schema.propertyKey("duration").Int().create(); 22 | schema.propertyKey("country").Text().create(); 23 | schema.propertyKey("production").Text().multiple().create(); 24 | schema.propertyKey("rating").Int().create(); 25 | 26 | // Define vertex labels 27 | schema.vertexLabel("genre").properties("genreId","name").create(); 28 | schema.vertexLabel("person").properties("personId","name").create(); 29 | schema.vertexLabel("user").properties("userId","age","gender").create(); 30 | schema.vertexLabel("movie").properties("movieId","title","year","duration","country","production").create(); 31 | 32 | // Define edge labels 33 | schema.edgeLabel("knows").connection("user","user").create(); 34 | schema.edgeLabel("rated").single().properties("rating").connection("user","movie").create(); 35 | schema.edgeLabel("belongsTo").single().connection("movie","genre").create(); 36 | schema.edgeLabel("actor").connection("movie","person").create(); // multiple() due to data 37 | schema.edgeLabel("director").single().connection("movie","person").create(); 38 | schema.edgeLabel("composer").single().connection("movie","person").create(); 39 | schema.edgeLabel("screenwriter").connection("movie","person").create(); // multiple() due to data 40 | schema.edgeLabel("cinematographer").single().connection("movie","person").create(); 41 | 42 | // Define vertex indexes 43 | schema.vertexLabel("genre").index("genresById").materialized().by("genreId").add(); 44 | schema.vertexLabel("genre").index("genresByName").materialized().by("name").add(); 45 | schema.vertexLabel("person").index("personsById").materialized().by("personId").add(); 46 | schema.vertexLabel("person").index("personsByName").materialized().by("name").add(); 47 | schema.vertexLabel("user").index("usersById").materialized().by("userId").add(); 48 | schema.vertexLabel("user").index("usersByAge").secondary().by("age").add(); 49 | schema.vertexLabel("movie").index("moviesById").materialized().by("movieId").add(); 50 | schema.vertexLabel("movie").index("moviesByTitle").materialized().by("title").add(); 51 | schema.vertexLabel("movie").index("moviesByYear").secondary().by("year").add(); 52 | 53 | // Define edge indexes 54 | schema.vertexLabel("user").index("toMoviesByRating").outE("rated").by("rating").add(); 55 | schema.vertexLabel("movie").index("toUsersByRating").inE("rated").by("rating").add(); 56 | -------------------------------------------------------------------------------- /killrvideo/verify.csv: -------------------------------------------------------------------------------- 1 | g.V().count()|10797 2 | g.E().count()|69054 3 | g.V().groupCount().by(both().count()).order(local).by(select(keys))|{1=6048, 2=1367, 3=556, 4=291, 5=155, 6=116, 7=76, 8=47, 9=30, 10=23, 11=16, 12=9, 13=3, 14=9, 15=1, 16=2, 17=2, 18=3, 19=2, 21=2, 23=5, 24=9, 25=7, 26=10, 27=10, 28=15, 29=11, 30=12, 31=22, 32=9, 33=16, 34=17, 35=15, 36=27, 37=27, 38=26, 39=35, 40=45, 41=40, 42=45, 43=50, 44=55, 45=59, 46=59, 47=60, 48=74, 49=62, 50=70, 51=63, 52=62, 53=74, 54=75, 55=57, 56=60, 57=49, 58=33, 59=49, 60=32, 61=32, 62=26, 63=26, 64=22, 65=16, 66=11, 67=12, 68=14, 69=12, 70=12, 71=8, 72=4, 73=12, 74=8, 75=9, 76=11, 77=7, 78=12, 79=3, 80=6, 81=8, 82=7, 83=5, 84=12, 85=11, 86=12, 87=8, 88=4, 89=5, 90=7, 91=5, 92=10, 93=12, 94=9, 95=4, 96=7, 97=6, 98=4, 99=8, 100=6, 101=6, 102=2, 103=8, 104=6, 105=3, 106=3, 107=3, 108=6, 109=3, 110=6, 111=4, 112=2, 113=7, 114=4, 115=2, 116=3, 117=5, 118=5, 119=3, 120=4, 121=1, 122=2, 123=4, 124=4, 125=1, 126=1, 127=4, 128=2, 129=1, 130=2, 131=2, 132=3, 133=1, 134=2, 135=2, 136=1, 137=1, 138=3, 139=2, 140=3, 142=2, 143=2, 145=2, 146=1, 147=4, 149=2, 151=1, 152=2, 153=4, 154=1, 156=1, 161=1, 162=1, 164=2, 165=3, 166=1, 167=1, 168=1, 173=2, 177=1, 180=1, 181=1, 183=1, 184=2, 185=2, 195=1, 196=2, 197=2, 198=1, 201=1, 211=1, 227=1, 300=1, 311=1} 4 | -------------------------------------------------------------------------------- /london-tube/Schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/london-tube/Schema.png -------------------------------------------------------------------------------- /london-tube/london-tube-map.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/london-tube/london-tube-map.pdf -------------------------------------------------------------------------------- /london-tube/london_tube.gryo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/london-tube/london_tube.gryo -------------------------------------------------------------------------------- /london-tube/london_tube_mapping.groovy: -------------------------------------------------------------------------------- 1 | config load_new: true, create_schema: false 2 | 3 | dir = "/tmp/tube/" 4 | 5 | vertexInput = File.csv(dir + "london_vertices.csv").delimiter(",").header("id","name","zone","is_rail","lines") 6 | edgesInput = File.csv(dir + "london_edges.csv").delimiter(",").header("from_id","to_id","line") 7 | 8 | vextexInput = vertexInput.map{it["lines"] = it["lines"].toString().split("\\|"); it["zone"] = it["zone"].toString().toDouble(); it["id"] = it["id"].toString().toInteger(); it} 9 | edgesInput = edgesInput.map{it["from_id"] = it["from_id"].toString().toInteger(); it["to_id"] = it["to_id"].toString().toInteger(); it} 10 | 11 | load(vextexInput).asVertices { 12 | isNew() 13 | label "station" 14 | key "id" 15 | } 16 | 17 | load(edgesInput).asEdges { 18 | isNew() 19 | label "connectedTo" 20 | outV "from_id", { 21 | exists() 22 | label "station" 23 | key "id" 24 | } 25 | inV "to_id", { 26 | exists() 27 | label "station" 28 | key "id" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /london-tube/schema.groovy: -------------------------------------------------------------------------------- 1 | // Either create the graph in studio and add the following in a cell 2 | // or uncomment and run the following and run with the gremlin console 3 | //:remote config alias reset 4 | //system.graph("london_tube").drop() 5 | //system.graph("london_tube").ifNotExists().create() 6 | //:remote config alias g london_tube.g 7 | //:remote config timeout max 8 | 9 | schema.propertyKey("zone").Double().single().create() 10 | schema.propertyKey("line").Text().single().create() 11 | schema.propertyKey("name").Text().single().create() 12 | schema.propertyKey("id").Int().single().create() 13 | schema.propertyKey("is_rail").Boolean().single().create() 14 | schema.propertyKey("lines").Text().multiple().create() 15 | schema.edgeLabel("connectedTo").multiple().properties("line").create() 16 | schema.vertexLabel("station").partitionKey("id").properties("name", "zone", "is_rail", "lines").create() 17 | schema.vertexLabel("station").index("search").search().by("name").asText().by("zone").by("is_rail").by("lines").asText().add() 18 | schema.vertexLabel("station").index("stationByName").materialized().by("name").add() 19 | schema.vertexLabel("station").index("toStationByLine").outE("connectedTo").by("line").add() 20 | schema.vertexLabel("station").index("fromStationByLine").inE("connectedTo").by("line").add() 21 | schema.edgeLabel("connectedTo").connection("station", "station").add() 22 | 23 | -------------------------------------------------------------------------------- /northwind/Northwind_Schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/northwind/Northwind_Schema.png -------------------------------------------------------------------------------- /northwind/README.md: -------------------------------------------------------------------------------- 1 | # Northwind 2 | 3 | The Northwind graph example is a subset of Microsoft's Northwind dataset found [here](https://northwinddatabase.codeplex.com). 4 | The data has been prepared and serialized with the [Kryo](http://tinkerpop.apache.org/docs/current/reference/#gryo-reader-writer) format in the data directory. It is to be used as a learning tool for 5 | translating SQL queries to gremlin traversals as featured on the [sql2gremlin](http://sql2gremlin.com) page. Once you've loaded the data, you will be able to run the various example traversals from the *sql2gremlin* page in Studio or on the gremlin console. 6 | However, while using DSE Graph in Development mode, you'll have to explicitly enable use of scans and lambdas to run the examples that require those: 7 | 8 | ``` 9 | schema.config().option('graph.allow_scan').set('true') 10 | graph.schema().config().option('graph.traversal_sources.g.restrict_lambda').set(false) 11 | ``` 12 | Note that scans are disabled by default for performance reasons; lambdas are disabled by default for both performance reasons and security concerns. 13 | 14 | You can choose to let it create the schema for you (default) or you can create the schema explicitly (recommended for Production) and 15 | load the data with `create_schema` set to **false** in the script or from the command-line. 16 | 17 | ## Datamodel visualization 18 | 19 | View the live schema visualization here 20 | [![datamodel screenshot](datamodel-screenshot.png)](https://s3.amazonaws.com/datastax-graph-schema-viewer/index.html#/?schema=northwind.json)
21 | 22 | ## Create the schema 23 | 24 | Included is a `schema.groovy` file. You can create your graph in Studio and copy and paste the schema statements 25 | to run there. Alternately, the statements can be run from the gremlin console. 26 | 27 | ## Example loading 28 | 29 | If you load the Kryo file from within the northwind directory, you don't need to specify the path. It will 30 | default to the data subdirectory to get the northwind.kryo file. Otherwise, specify the full path with the 31 | `inputfile` parameter. 32 | 33 | Examples of loading the northwind data: 34 | 35 | ``` 36 | # From the northwind directory 37 | graphloader -graph northwind -address localhost northwind-mapping.groovy 38 | ``` 39 | 40 | ``` 41 | # Alternatively, explicitly specify where the data files are 42 | graphloader -graph northwind -address localhost northwind-mapping.groovy -inputpath ~/graph-examples/northwind/data/ 43 | ``` 44 | 45 | ## Supplemental data 46 | 47 | ### Supplemental data is not currently working as we change to custom vertex ids 48 | 49 | Some supplemental data has been added in csv files to provide some more connectivity within the data. It is generated data, 50 | that includes things like relationships between customers (isRelatedTo and isFriendsWith), customer product ratings (rated), 51 | and so forth. The relationships include the relationship type, the friendships include an affinity score, and the identities 52 | come with a confidence level to make the relationships more interesting to play with. 53 | 54 | Examples of loading the supplemental data: 55 | 56 | ``` 57 | # From the northwind directory 58 | graphloader -graph northwind -address localhost supplemental-data-mapping.groovy 59 | ``` 60 | 61 | ``` 62 | # Alternatively, explicitly specify where the data files are 63 | graphloader -graph northwind -address localhost supplemental-data-mapping.groovy -inputpath ~/graph-examples/northwind/data/ 64 | ``` 65 | -------------------------------------------------------------------------------- /northwind/code/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.datastax 4 | northwind 5 | 1.0.0 6 | 7 | 8 | 9 | com.datastax.dse 10 | dse-java-driver-core 11 | 1.3.0 12 | 13 | 14 | com.datastax.dse 15 | dse-java-driver-graph 16 | 1.3.0 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /northwind/code/src/main/java/com/datastax/examples/northwind/Northwind.java: -------------------------------------------------------------------------------- 1 | package com.datastax.examples.northwind; 2 | 3 | import com.datastax.driver.dse.DseCluster; 4 | import com.datastax.driver.dse.DseSession; 5 | import com.datastax.driver.dse.graph.GraphOptions; 6 | import com.datastax.driver.dse.graph.GraphResultSet; 7 | import com.datastax.driver.dse.graph.SimpleGraphStatement; 8 | import com.datastax.driver.dse.graph.Vertex; 9 | 10 | public class Northwind { 11 | 12 | public static void main(String [] args) throws Exception { 13 | 14 | DseCluster dseCluster = DseCluster.builder() 15 | .addContactPoint("localhost") 16 | .withGraphOptions(new GraphOptions().setGraphName("northwind")) 17 | .build(); 18 | 19 | DseSession dseSession = dseCluster.connect(); 20 | 21 | basicAdd(dseSession); 22 | 23 | System.exit(0); 24 | } 25 | 26 | /** 27 | * Create a vertex and edge using the synchronous methods 28 | */ 29 | private static void basicAdd(DseSession dseSession) { 30 | 31 | String name = "Catherine Dewey"; 32 | int age = 38; 33 | 34 | dseSession.executeGraph( 35 | new SimpleGraphStatement( 36 | "g.addV(label, 'networkMember', 'name', name, 'age', age)") 37 | .set("name", name) 38 | .set("age", String.valueOf(age)) 39 | ); 40 | 41 | // Add edge between two existing vertices 42 | dseSession.executeGraph( 43 | new SimpleGraphStatement( 44 | "customer = g.V().has('customer', 'name', name).next();" + 45 | "networkMember = g.V().has('networkMember', 'name', name).next();" + 46 | "customer.addEdge('isMember', networkMember);") 47 | .set("name", name) 48 | ); 49 | 50 | // Check to make sure the vertex was added 51 | GraphResultSet rs = dseSession.executeGraph( 52 | new SimpleGraphStatement( 53 | "g.V().has('networkMember', 'name', name)") 54 | .set("name", name) 55 | ); 56 | Vertex v = rs.one().asVertex(); 57 | 58 | System.out.println(v); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /northwind/data/facebook_members.csv: -------------------------------------------------------------------------------- 1 | name|age 2 | Giovanni Rovelli|33 3 | Jean Fresnière|48 4 | Alexander Feuer|31 5 | Simon Crowther|36 6 | Yvonne Moncada|21 7 | Henriette Pfalzheim|39 8 | Marie Bertrand|54 9 | Guillermo Fernández|52 10 | Georg Pipps|70 11 | Isabel de Castro|65 12 | Bernardo Batista|64 13 | Lúcia Carvalho|62 14 | Horst Kloss|30 15 | Sergio Gutiérrez|36 16 | Paula Wilson|30 17 | Maurizio Moroni|39 18 | Janete Limeira|42 19 | Michael Holz|32 20 | Alejandra Camino|44 21 | Jonas Bergulfsen|46 22 | Jose Pavarotti|34 23 | Hari Kumar|70 24 | Jytte Petersen|43 25 | Dominique Perrier|29 26 | Art Braunschweiger|63 27 | Pascale Cartrain|41 28 | Aria Cruz|28 29 | Diego Roel|36 30 | Martine Rancé|46 31 | Maria Larsson|63 32 | Peter Franken|66 33 | Carine Schmitt|38 34 | Paolo Accorti|30 35 | Lino Rodriguez|44 36 | Eduardo Saavedra|38 37 | José Pedro Freyre|18 38 | André Fonseca|36 39 | Howard Snyder|37 40 | Manuel Pereira|39 41 | Mario Pontes|26 42 | Carlos Hernández|69 43 | Yoshi Latimer|55 44 | Patricia McKenna|33 45 | Helen Bennett|38 46 | Philip Cramer|21 47 | Daniel Tonini|67 48 | Annette Roulet|20 49 | Yoshi Tannamuri|68 50 | John Steel|31 51 | Renate Messner|20 52 | Jaime Yorres|46 53 | Carlos González|27 54 | Felipe Izquierdo|44 55 | Fran Wilson|46 56 | Maria Anders|38 57 | Ana Trujillo|25 58 | Antonio Moreno|59 59 | Thomas Hardy|42 60 | Christina Berglund|32 61 | Hanna Moos|67 62 | Frédérique Citeaux|28 63 | Martín Sommer|39 64 | Laurence Lebihan|60 65 | Victoria Ashworth|20 66 | Patricio Simpson|53 67 | Francisco Chang|49 68 | Pedro Afonso|66 69 | Elizabeth Brown|45 70 | Sven Ottlieb|21 71 | Janine Labrune|25 72 | Ann Devon|67 73 | Roland Mendel|34 74 | Liz Nixon|70 75 | Liu Wong|50 76 | Miguel Angel Paolino|27 77 | Anabela Domingues|52 78 | Helvetius Nagy|33 79 | Palle Ibsen|33 80 | Mary Saveley|52 81 | Paul Henriot|62 82 | Rita Müller|46 83 | Pirkko Koskitalo|64 84 | Karl Jablonski|41 85 | Matti Karttunen|21 86 | Zbyszek Piestrzeniewicz|60 -------------------------------------------------------------------------------- /northwind/data/identity_c2fb.csv: -------------------------------------------------------------------------------- 1 | name|confidence 2 | Giovanni Rovelli|82 3 | Jean Fresnière|34 4 | Alexander Feuer|68 5 | Simon Crowther|68 6 | Yvonne Moncada|59 7 | Henriette Pfalzheim|66 8 | Marie Bertrand|31 9 | Guillermo Fernández|65 10 | Georg Pipps|67 11 | Isabel de Castro|46 12 | Bernardo Batista|100 13 | Lúcia Carvalho|47 14 | Horst Kloss|90 15 | Sergio Gutiérrez|81 16 | Paula Wilson|87 17 | Maurizio Moroni|66 18 | Janete Limeira|90 19 | Michael Holz|53 20 | Alejandra Camino|49 21 | Jonas Bergulfsen|57 22 | Jose Pavarotti|54 23 | Hari Kumar|99 24 | Jytte Petersen|44 25 | Dominique Perrier|75 26 | Art Braunschweiger|94 27 | Pascale Cartrain|91 28 | Aria Cruz|80 29 | Diego Roel|93 30 | Martine Rancé|70 31 | Maria Larsson|97 32 | Peter Franken|48 33 | Carine Schmitt|63 34 | Paolo Accorti|64 35 | Lino Rodriguez|53 36 | Eduardo Saavedra|53 37 | José Pedro Freyre|48 38 | André Fonseca|82 39 | Howard Snyder|55 40 | Manuel Pereira|91 41 | Mario Pontes|60 42 | Carlos Hernández|50 43 | Yoshi Latimer|38 44 | Patricia McKenna|86 45 | Helen Bennett|93 46 | Philip Cramer|62 47 | Daniel Tonini|89 48 | Annette Roulet|80 49 | Yoshi Tannamuri|52 50 | John Steel|49 51 | Renate Messner|95 52 | Jaime Yorres|41 53 | Carlos González|81 54 | Felipe Izquierdo|46 55 | Fran Wilson|79 56 | Maria Anders|63 57 | Ana Trujillo|80 58 | Antonio Moreno|97 59 | Thomas Hardy|89 60 | Christina Berglund|95 61 | Hanna Moos|52 62 | Frédérique Citeaux|69 63 | Martín Sommer|70 64 | Laurence Lebihan|99 65 | Victoria Ashworth|51 66 | Patricio Simpson|72 67 | Francisco Chang|98 68 | Pedro Afonso|31 69 | Elizabeth Brown|63 70 | Sven Ottlieb|54 71 | Janine Labrune|60 72 | Ann Devon|36 73 | Roland Mendel|56 74 | Liz Nixon|52 75 | Liu Wong|78 76 | Miguel Angel Paolino|92 77 | Anabela Domingues|65 78 | Helvetius Nagy|50 79 | Palle Ibsen|80 80 | Mary Saveley|94 81 | Paul Henriot|98 82 | Rita Müller|38 83 | Pirkko Koskitalo|52 84 | Karl Jablonski|97 85 | Matti Karttunen|97 86 | Zbyszek Piestrzeniewicz|71 87 | -------------------------------------------------------------------------------- /northwind/data/isRelatedTo.csv: -------------------------------------------------------------------------------- 1 | nameFrom|nameTo|relationship 2 | Giovanni Rovelli|Matti Karttunen|parent 3 | Alexander Feuer|John Steel|parent 4 | Simon Crowther|Eduardo Saavedra|sibling 5 | Yvonne Moncada|Manuel Pereira|parent 6 | Marie Bertrand|Sergio Gutiérrez|sibling 7 | Guillermo Fernández|Zbyszek Piestrzeniewicz|parent 8 | Georg Pipps|Patricia McKenna|parent 9 | Isabel de Castro|Ana Trujillo|sibling 10 | Bernardo Batista|Pascale Cartrain|sibling 11 | Horst Kloss|Frédérique Citeaux|sibling 12 | Sergio Gutiérrez|Janete Limeira|parent 13 | Paula Wilson|Daniel Tonini|parent 14 | Maurizio Moroni|Bernardo Batista|parent 15 | Janete Limeira|Carlos Hernández|parent 16 | Alejandra Camino|John Steel|parent 17 | Jose Pavarotti|Sven Ottlieb|sibling 18 | Hari Kumar|Jose Pavarotti|parent 19 | Jytte Petersen|Helvetius Nagy|parent 20 | Dominique Perrier|Yoshi Latimer|sibling 21 | Art Braunschweiger|Ann Devon|parent 22 | Pascale Cartrain|Lino Rodriguez|parent 23 | Aria Cruz|Horst Kloss|sibling 24 | Martine Rancé|Liu Wong|parent 25 | Peter Franken|John Steel|sibling 26 | Carine Schmitt|Ann Devon|parent 27 | Paolo Accorti|Palle Ibsen|sibling 28 | Lino Rodriguez|Antonio Moreno|parent 29 | Eduardo Saavedra|Henriette Pfalzheim|sibling 30 | José Pedro Freyre|Frédérique Citeaux|parent 31 | André Fonseca|Hari Kumar|parent 32 | Howard Snyder|Mary Saveley|sibling 33 | Manuel Pereira|Miguel Angel Paolino|sibling 34 | Mario Pontes|Anabela Domingues|sibling 35 | Carlos Hernández|André Fonseca|sibling 36 | Yoshi Latimer|Paula Wilson|parent 37 | Patricia McKenna|Maria Larsson|parent 38 | Helen Bennett|John Steel|parent 39 | Daniel Tonini|Maria Anders|sibling 40 | Yoshi Tannamuri|Ana Trujillo|sibling 41 | Renate Messner|Matti Karttunen|parent 42 | Jaime Yorres|Liu Wong|parent 43 | Felipe Izquierdo|Karl Jablonski|sibling 44 | Fran Wilson|Jaime Yorres|sibling 45 | Maria Anders|Yoshi Tannamuri|sibling 46 | Christina Berglund|Dominique Perrier|sibling 47 | Hanna Moos|Miguel Angel Paolino|parent 48 | Frédérique Citeaux|Helvetius Nagy|parent 49 | Martín Sommer|Guillermo Fernández|sibling 50 | Laurence Lebihan|Jose Pavarotti|parent 51 | Victoria Ashworth|Peter Franken|sibling 52 | Patricio Simpson|Paul Henriot|sibling 53 | Francisco Chang|Howard Snyder|sibling 54 | Pedro Afonso|Martín Sommer|sibling 55 | Elizabeth Brown|Victoria Ashworth|parent 56 | Sven Ottlieb|Lino Rodriguez|sibling 57 | Janine Labrune|Francisco Chang|sibling 58 | Ann Devon|Frédérique Citeaux|parent 59 | Liz Nixon|Hari Kumar|sibling 60 | Liu Wong|Patricia McKenna|sibling 61 | Miguel Angel Paolino|Liu Wong|parent 62 | Anabela Domingues|Giovanni Rovelli|parent 63 | Helvetius Nagy|Pirkko Koskitalo|sibling 64 | Palle Ibsen|Francisco Chang|parent 65 | Mary Saveley|Isabel de Castro|parent 66 | Paul Henriot|Guillermo Fernández|parent 67 | Pirkko Koskitalo|Ana Trujillo|sibling 68 | Karl Jablonski|Hari Kumar|sibling 69 | Zbyszek Piestrzeniewicz|Jonas Bergulfsen|sibling 70 | -------------------------------------------------------------------------------- /northwind/data/northwind.kryo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/northwind/data/northwind.kryo -------------------------------------------------------------------------------- /northwind/datamodel-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/northwind/datamodel-screenshot.png -------------------------------------------------------------------------------- /northwind/northwind-mapping.groovy: -------------------------------------------------------------------------------- 1 | // Use the separate schema.groovy to create the schema 2 | config create_schema: false, load_new: true 3 | 4 | inputfile = 'northwind.kryo' 5 | 6 | // If the user specifies an inputpath on the command-line, use that. 7 | // Otherwise check the data directory from the data directory from where the loader is run. 8 | if (inputpath == '') 9 | path = new java.io.File('.').getCanonicalPath() + '/data/' 10 | else 11 | path = inputpath + '/' 12 | 13 | def source = Graph.file(path + inputfile).gryo() 14 | 15 | //Specifies what data source to load using which mapper 16 | load(source.vertices()).asVertices { 17 | labelField "~label" 18 | key "~id", "id" 19 | } 20 | 21 | load(source.edges()).asEdges { 22 | labelField "~label" 23 | outV "outV", { 24 | labelField "~label" 25 | key "~id", "id" 26 | } 27 | inV "inV", { 28 | labelField "~label" 29 | key "~id", "id" 30 | } 31 | } -------------------------------------------------------------------------------- /northwind/northwind-mapping.groovy.config: -------------------------------------------------------------------------------- 1 | name: "inputpath", type: String, defaultValue: "", description: "The location of the graph data to be loaded." 2 | -------------------------------------------------------------------------------- /northwind/supplemental-data-mapping.groovy: -------------------------------------------------------------------------------- 1 | config create_schema: true, load_new: false 2 | 3 | // If the user specifies an inputpath on the command-line, use that. 4 | // Otherwise check the data directory from the data directory from where the loader is run. 5 | if (inputpath == '') 6 | path = new java.io.File('.').getCanonicalPath() + '/data/' 7 | else 8 | path = inputpath + '/' 9 | 10 | def fbMembersInput = File.csv(path + 'facebook_members.csv').delimiter('|') 11 | def identitiesInput = File.csv(path + 'identity_c2fb.csv').delimiter('|') 12 | def isFriendsWithInput = File.csv(path + 'isFriendsWith.csv').delimiter('|') 13 | def isRelatedToInput = File.csv(path + 'isRelatedTo.csv').delimiter('|') 14 | def ratedInput = File.csv(path + 'rated.csv').delimiter('|') 15 | 16 | //Specifies what data source to load using which mapper 17 | load(fbMembersInput).asVertices { 18 | label "networkMember" 19 | key "name" 20 | } 21 | 22 | load(identitiesInput).asEdges { 23 | label 'isMember' 24 | outV 'name', { 25 | label 'customer' 26 | key 'name' 27 | } 28 | inV 'name', { 29 | label 'networkMember' 30 | key 'name' 31 | } 32 | } 33 | 34 | load(isFriendsWithInput).asEdges { 35 | label "isFriendsWith" 36 | outV "nameFrom", { 37 | label "networkMember" 38 | key "name" 39 | } 40 | inV "nameTo", { 41 | label "networkMember" 42 | key "name" 43 | } 44 | } 45 | 46 | load(isRelatedToInput).asEdges { 47 | label "isRelatedTo" 48 | outV "nameFrom", { 49 | label "networkMember" 50 | key "name" 51 | } 52 | inV "nameTo", { 53 | label "networkMember" 54 | key "name" 55 | } 56 | } 57 | 58 | load(ratedInput).asEdges { 59 | label "rated" 60 | outV "customerName", { 61 | label "customer" 62 | key "name" 63 | } 64 | inV "productId", { 65 | label "product" 66 | key "id" 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /northwind/supplemental-data-mapping.groovy.config: -------------------------------------------------------------------------------- 1 | name: "inputpath", type: String, defaultValue: "", description: "The location of the graph data to be loaded." 2 | -------------------------------------------------------------------------------- /northwind/verify.csv: -------------------------------------------------------------------------------- 1 | g.V().count()|3294 2 | g.E().count()|6849 3 | g.V().groupCount().by(both().count()).order(local).by(select(keys))|{1=17, 2=2167, 3=152, 4=299, 5=268, 6=148, 7=47, 8=15, 9=13, 10=3, 11=7, 12=12, 13=5, 14=10, 15=9, 16=3, 17=8, 18=3, 19=7, 20=5, 21=9, 22=7, 23=8, 25=2, 26=1, 27=6, 28=1, 29=1, 30=1, 31=3, 33=5, 34=4, 35=3, 37=2, 38=3, 39=2, 40=2, 41=4, 42=2, 43=1, 44=1, 45=5, 46=5, 48=2, 50=1, 52=2, 54=1, 55=1, 56=1, 58=1, 60=1, 63=1, 68=1, 73=1, 101=1, 105=1, 124=1, 128=1, 157=1} 4 | -------------------------------------------------------------------------------- /paging-graph-results/.gitignore: -------------------------------------------------------------------------------- 1 | # file: ~/.gitignore_global 2 | .DS_Store 3 | .idea 4 | 5 | /target 6 | 7 | # Compiled class file 8 | *.class 9 | 10 | # Log file 11 | *.log 12 | 13 | # BlueJ files 14 | *.ctxt 15 | 16 | # Mobile Tools for Java (J2ME) 17 | .mtj.tmp/ 18 | 19 | # Package Files # 20 | *.jar 21 | *.war 22 | *.nar 23 | *.ear 24 | *.zip 25 | *.tar.gz 26 | *.rar 27 | 28 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 29 | hs_err_pid* -------------------------------------------------------------------------------- /paging-graph-results/README.md: -------------------------------------------------------------------------------- 1 | # Paging Graph Results - Java Driver 2 | ## Summary 3 | This example repo demonstrates how to use the continuous paging functionality available with DataStax graph to page results 4 | as they are returned from DataStax Graph. This repo shows how to use this paging functionality with both the synchronous 5 | and asynchronous methods to stream back a continuous set of results from long running graph queries. 6 | 7 | ## Prerequisites 8 | 9 | * This only works on the 6.8 Release of DataStax Graph, this was built using the 1.8.2.20190711-LABS Experimental release 10 | * Java 8 11 | * DataStax Enterprise Java Driver for the 1.8.2.20190711-LABS Experimental 6.8 DataStax Graph Release 12 | * Maven 13 | * A DataStax Core Graph created and configured on your 6.8 cluster 14 | 15 | ## Building and Running 16 | 17 | In order to build this we need to run a Maven build using: 18 | 19 | ```mvn clean package``` 20 | 21 | This will build and package a fat jar. Once completed you can run this program from the command line using: 22 | 23 | ``` 24 | java -cp ./target/paging-graph-results-0.1-jar-with-dependencies.jar com.datastax.graphpractice.example.App 25 | ``` 26 | -------------------------------------------------------------------------------- /paging-graph-results/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | paging-graph-results 8 | paging-graph-results 9 | 0.1 10 | 11 | 12 | 13 | com.datastax.dse 14 | dse-java-driver-graph 15 | 1.8.2.20190711-LABS 16 | 17 | 18 | com.google.guava 19 | guava 20 | 19.0 21 | 22 | 23 | 24 | 25 | 26 | org.apache.maven.plugins 27 | maven-assembly-plugin 28 | 2.4.1 29 | 30 | 31 | 32 | jar-with-dependencies 33 | 34 | 35 | 36 | 37 | com.mkyong.core.utils.App 38 | 39 | 40 | 41 | 42 | 43 | 44 | make-assembly 45 | 46 | package 47 | 48 | single 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /pokemon/README.md: -------------------------------------------------------------------------------- 1 | # Gotta Graph 'em All! 2 | ![Alt text](https://www.datastax.com/wp-content/uploads/2016/08/dsegraph.jpg) 3 | 4 | This demo is intended to help get you started with DSE Graph. It includes schemas, data, and mapper script for the DataStax Graph Loader. 5 | 6 | ##About the Data 7 | The data comes to us from the [pokeapi](https://github.com/PokeAPI/pokeapi). I took the liberty of cleaning the data files and choosing the ones that had relationships applicable to a graph database. I've also changed the file and header names to help new comers better understand what's happening inside DSE Graph. 8 | 9 | 10 | ##Prerequisites 11 | * [Learn some Graph](https://academy.datastax.com/courses/ds330-datastax-enterprise-graph) <- this will give you ideas on how to query this graph 12 | * [DataStax Graph Loader](https://academy.datastax.com/downloads/download-drivers) 13 | * [DataStax Enterprise 5.0 or greater](https://www.datastax.com/downloads) 14 | * [DataStax Studio 1.0 or greater](https://www.datastax.com/downloads) 15 | 16 | 17 | ##How-to: 18 | 1. Start DataStax Enterprise in graph mode mode 19 | 2. Start DataStax Studio - on your local machine it'll bind to http://localhost:9091 20 | 3. Edit ```poke_mapper.groovy``` so that the paths for *inputfileV* and *inputfileE* files = `'/path/to/this/directory/data/'` 21 | 22 | ##Let's get started 23 | 24 | In DataStax Studio create a new connection with a new graph called 'poke_graph' (or what ever you want the graph to be called) 25 | ![Alt text](http://i.imgur.com/zNrR722.png) 26 | 27 | ###Next, paste the schema from the `schema.groovy` file into a new gremlin box: 28 | ![Alt text](http://i.imgur.com/XB7PGkU.png) 29 | 30 | If you'd like to add more indices for different types of traversals, you can always add them after the fact. The ones in the schema file are for the Graph Loader to do look ups and match vertices to edges. 31 | 32 | Click the `real-time` play button to execute. When it finishes, hit the `schema` button at the top right of Studio. 33 | View the live schema visualization here 34 | [![Alt text](http://i.imgur.com/M8cSueW.png)](https://s3.amazonaws.com/datastax-graph-schema-viewer/index.html#/?schema=pokegraph.json) 35 | 36 | Note, there's plenty of other connections we can make with this dataset. Feel free to explore and play around! 37 | 38 | 39 | ###Now we're going to load the data 40 | 41 | `sudo ./graphloader /path/to/poke_mapper.groovy -graph poke_graph -address localhost -abort_on_prep_errors false 42 | ` 43 | 44 | Some of the properties within the CSV files contain empty fields which is OK for this demo but will cause errors. This is why we set the `-abort_on_prep_errors` flag 45 | 46 | 47 | 48 | ###Play time! Remember that Studio truncates results to 1000 by default. 49 | 50 | ![Alt text](http://i.imgur.com/ptyBTBb.png) 51 | ![Alt text](http://i.imgur.com/fOFgwKe.png) 52 | -------------------------------------------------------------------------------- /pokemon/data/edges/category_has_pocket_type.csv: -------------------------------------------------------------------------------- 1 | category_id,pocket_id 2 | 1,7 3 | 2,5 4 | 3,5 5 | 4,5 6 | 5,5 7 | 6,5 8 | 7,5 9 | 8,5 10 | 9,1 11 | 10,1 12 | 11,1 13 | 12,1 14 | 13,1 15 | 14,1 16 | 15,1 17 | 16,1 18 | 17,1 19 | 18,1 20 | 19,1 21 | 20,8 22 | 21,8 23 | 22,8 24 | 23,8 25 | 24,1 26 | 25,6 27 | 26,2 28 | 27,2 29 | 28,2 30 | 29,2 31 | 30,2 32 | 32,1 33 | 33,3 34 | 34,3 35 | 35,1 36 | 36,1 37 | 37,4 38 | 38,7 39 | 39,3 40 | 40,8 41 | 41,8 42 | 42,1 43 | 43,7 44 | 44,1 45 | 10001,8 -------------------------------------------------------------------------------- /pokemon/data/vertices/egg_groups.csv: -------------------------------------------------------------------------------- 1 | egg_groups_id,egg_groups 2 | 1,monster 3 | 2,water1 4 | 3,bug 5 | 4,flying 6 | 5,ground 7 | 6,fairy 8 | 7,plant 9 | 8,humanshape 10 | 9,water3 11 | 10,mineral 12 | 11,indeterminate 13 | 12,water2 14 | 13,ditto 15 | 14,dragon 16 | 15,no-eggs 17 | -------------------------------------------------------------------------------- /pokemon/data/vertices/genders.csv: -------------------------------------------------------------------------------- 1 | gender_id,gender 2 | 1,female 3 | 2,male 4 | 3,genderless 5 | -------------------------------------------------------------------------------- /pokemon/data/vertices/item_categories.csv: -------------------------------------------------------------------------------- 1 | category_id,pocket_id,category 2 | 1,7,stat-boosts 3 | 2,5,effort-drop 4 | 3,5,medicine 5 | 4,5,other 6 | 5,5,in-a-pinch 7 | 6,5,picky-healing 8 | 7,5,type-protection 9 | 8,5,baking-only 10 | 9,1,collectibles 11 | 10,1,evolution 12 | 11,1,spelunking 13 | 12,1,held-items 14 | 13,1,choice 15 | 14,1,effort-training 16 | 15,1,bad-held-items 17 | 16,1,training 18 | 17,1,plates 19 | 18,1,species-specific 20 | 19,1,type-enhancement 21 | 20,8,event-items 22 | 21,8,gameplay 23 | 22,8,plot-advancement 24 | 23,8,unused 25 | 24,1,loot 26 | 25,6,all-mail 27 | 26,2,vitamins 28 | 27,2,healing 29 | 28,2,pp-recovery 30 | 29,2,revival 31 | 30,2,status-cures 32 | 32,1,mulch 33 | 33,3,special-balls 34 | 34,3,standard-balls 35 | 35,1,dex-completion 36 | 36,1,scarves 37 | 37,4,all-machines 38 | 38,7,flutes 39 | 39,3,apricorn-balls 40 | 40,8,apricorn-box 41 | 41,8,data-cards 42 | 42,1,jewels 43 | 43,7,miracle-shooter 44 | 44,1,mega-stones 45 | 10001,8,xy-unknown 46 | -------------------------------------------------------------------------------- /pokemon/data/vertices/item_pockets.csv: -------------------------------------------------------------------------------- 1 | pocket_id,pocket_type 2 | 1,misc 3 | 2,medicine 4 | 3,pokeballs 5 | 4,machines 6 | 5,berries 7 | 6,mail 8 | 7,battle 9 | 8,key 10 | -------------------------------------------------------------------------------- /pokemon/data/vertices/regions.csv: -------------------------------------------------------------------------------- 1 | region_id,region 2 | 1,kanto 3 | 2,johto 4 | 3,hoenn 5 | 4,sinnoh 6 | 5,unova 7 | 6,kalos 8 | -------------------------------------------------------------------------------- /pokemon/data/vertices/stats.csv: -------------------------------------------------------------------------------- 1 | stat_id,stat 2 | 1,hp 3 | 2,attack 4 | 3,defense 5 | 4,special-attack 6 | 5,special-defense 7 | 6,speed 8 | 7,accuracy 9 | 8,evasion -------------------------------------------------------------------------------- /pokemon/data/vertices/types.csv: -------------------------------------------------------------------------------- 1 | type_id,type 2 | 1,normal 3 | 2,fighting 4 | 3,flying 5 | 4,poison 6 | 5,ground 7 | 6,rock 8 | 7,bug 9 | 8,ghost 10 | 9,steel 11 | 10,fire 12 | 11,water 13 | 12,grass 14 | 13,electric 15 | 14,psychic 16 | 15,ice 17 | 16,dragon 18 | 17,dark 19 | 18,fairy 20 | 10001,unknown 21 | 10002,shadow -------------------------------------------------------------------------------- /pokemon/graphloader_command.txt: -------------------------------------------------------------------------------- 1 | # if running from pokemon directory 2 | /path/to/graphloader /path/to/poke_mapper.groovy -graph poke_graph -address localhost -abort_on_prep_errors false 3 | 4 | # if running from somewhere else 5 | /path/to/graphloader /path/to/poke_mapper.groovy -graph poke_graph -address localhost -abort_on_prep_errors false -inputpath /path/to/directory/containing/data 6 | -------------------------------------------------------------------------------- /pokemon/poke_mapper.groovy.config: -------------------------------------------------------------------------------- 1 | name: "inputpath", type: String, defaultValue: "", description: "The location of the graph data to be loaded." 2 | -------------------------------------------------------------------------------- /traversal-builder/README.md: -------------------------------------------------------------------------------- 1 | # Traversal Builder Example 2 | 3 | This project demonstrates how to [implement](src/main/java/com/datastax/examples/builder/shortestPath/ShortestPathQueryBuilder.java) and 4 | [use](src/main/java/com/datastax/examples/builder/ShortestPathTraversals.java) a traversal builder that can significantly simplify 5 | the construction of complex traversals. 6 | 7 | The graph being used in this project is based on [TinkerPop's modern graph](http://tinkerpop.apache.org/docs/current/reference/#tinkerpop-modern). 8 | The only difference is an added `uses` edge between `peter` and `ripple`. 9 | 10 | ## Running the sample application 11 | 12 | To start the sample application, which is a simple CLI application, run the following command from the application's root directory: 13 | 14 | ```bash 15 | bin/run.sh 16 | ``` 17 | 18 | This shell script will start the application, or recompile and start the application if any source file is newer than the current binary file. 19 | 20 | The application can run without a connection to a DSE cluster (in that case, it will execute all traversals on a `TinkerGraph`). The application's 21 | user interface will show all the available commands that can be used to establish a connection to a DSE cluster and build/execute certain 22 | traversals (note, that there's also support for tab completion). 23 | -------------------------------------------------------------------------------- /traversal-builder/bin/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd `dirname $0` 4 | 5 | SRC_DIR="../src/" 6 | TGT_DIR="../target/" 7 | JAR_FILE="traversal-builder.jar" 8 | 9 | findJarFile() { 10 | jarFile=$(find $TGT_DIR -name "traversal-builder-*-jar-with-dependencies.jar" -printf '%T+ %p\n' | sort -r | head -n1 | awk '{print $2}') 11 | } 12 | 13 | recompile() { 14 | pushd ../ > /dev/null 15 | mvn package -q 2> /dev/null 16 | popd > /dev/null 17 | findJarFile 18 | cp -p $jarFile $JAR_FILE 19 | } 20 | 21 | if [ -d $TGT_DIR ]; then 22 | findJarFile 23 | if [ -f $jarFile ]; then 24 | cp -p $jarFile $JAR_FILE 25 | newestSourceFile=$(find $SRC_DIR -type f -printf '%T+ %p\n' | sort -r | head -n1 | awk '{print $2}') 26 | if [ $newestSourceFile -nt $JAR_FILE ]; then 27 | recompile 28 | fi 29 | else 30 | recompile 31 | fi 32 | else 33 | recompile 34 | fi 35 | 36 | java -cp traversal-builder.jar com.datastax.examples.builder.App 37 | -------------------------------------------------------------------------------- /traversal-builder/bin/traversal-builder.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastax/graph-examples/fa69b1178183f98df76e0808861cdb330991e19d/traversal-builder/bin/traversal-builder.jar -------------------------------------------------------------------------------- /traversal-builder/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | com.datastax.examples 8 | traversal-builder 9 | 1.0.0 10 | 11 | 12 | 2.2.0 13 | 3.12.1 14 | 3.4.3 15 | 16 | 17 | 18 | 19 | com.datastax.dse 20 | dse-java-driver-core 21 | ${driver.version} 22 | 23 | 24 | org.apache.tinkerpop 25 | gremlin-core 26 | ${tinkerpop.version} 27 | 28 | 29 | org.apache.tinkerpop 30 | gremlin-groovy 31 | ${tinkerpop.version} 32 | 33 | 34 | org.apache.tinkerpop 35 | tinkergraph-gremlin 36 | ${tinkerpop.version} 37 | 38 | 39 | org.jline 40 | jline 41 | ${jline.version} 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.apache.maven.plugins 49 | maven-compiler-plugin 50 | 51 | 1.8 52 | 1.8 53 | 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-assembly-plugin 58 | 2.6 59 | 60 | 61 | jar-with-dependencies 62 | 63 | 64 | 65 | com.datastax.examples.builder.App 66 | 67 | 68 | 69 | 70 | 71 | make-assembly 72 | package 73 | 74 | single 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /traversal-builder/src/main/java/com/datastax/examples/builder/AppState.java: -------------------------------------------------------------------------------- 1 | package com.datastax.examples.builder; 2 | 3 | /** 4 | * @author Daniel Kuppitz (http://gremlin.guru) 5 | */ 6 | public enum AppState { 7 | MAIN, 8 | GRAPH, 9 | CONNECT, 10 | DISCONNECT, 11 | TRAVERSAL, 12 | RESULT, 13 | TRAVERSAL_RESULT, 14 | ERROR 15 | } 16 | -------------------------------------------------------------------------------- /traversal-builder/src/main/java/com/datastax/examples/builder/Commands.java: -------------------------------------------------------------------------------- 1 | package com.datastax.examples.builder; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * @author Daniel Kuppitz (http://gremlin.guru) 9 | */ 10 | class Commands { 11 | 12 | static Pattern GRAPH = Pattern.compile("^(g|graph)$"); 13 | static Pattern CONNECT = Pattern.compile("^(c|connect)$"); 14 | static Pattern DISCONNECT = Pattern.compile("^(d|disconnect)$"); 15 | static Pattern SHOW = Pattern.compile("^(s|show)[ ]+([0-9]+)$"); 16 | static Pattern RUN = Pattern.compile("^(r|run)[ ]+([0-9]+)$"); 17 | static Pattern EXIT = Pattern.compile("^(x|exit)$"); 18 | 19 | private static List COMMANDS = new ArrayList<>(); 20 | 21 | /* 22 | * Initialize application commands. 23 | */ 24 | static { 25 | COMMANDS.add(new Command("graph", "Visualize the sample graph being used")); 26 | COMMANDS.add(new Command("connect", "Connect to a DSE cluster")); 27 | COMMANDS.add(new Command("disconnect", "Disconnect from DSE cluster")); 28 | COMMANDS.add(new Command("show N", "Show the generated traversal for use-case N")); 29 | COMMANDS.add(new Command("run N", "Execute the generated traversal for use-case N")); 30 | COMMANDS.add(new Command("exit", "Exit the application")); 31 | } 32 | 33 | static Iterable get() { 34 | return COMMANDS; 35 | } 36 | 37 | static class Command { 38 | 39 | final String command; 40 | final String description; 41 | 42 | Command(String command, String description) { 43 | this.command = command; 44 | this.description = description; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /traversal-builder/src/main/resources/graph.groovy: -------------------------------------------------------------------------------- 1 | g.V().drop().iterate() 2 | g.addV("person").property("name", "marko").property("age", 29).as("marko"). 3 | addV("person").property("name", "vadas").property("age", 27).as("vadas"). 4 | addV("software").property("name", "lop").property("lang", "java").as("lop"). 5 | addV("person").property("name", "josh").property("age", 32).as("josh"). 6 | addV("software").property("name", "ripple").property("lang", "java").as("ripple"). 7 | addV("person").property("name", "peter").property("age", 35).as("peter"). 8 | addE("knows").from("marko").to("vadas").property("weight", 0.5). 9 | addE("knows").from("marko").to("josh").property("weight", 1.0). 10 | addE("created").from("marko").to("lop").property("weight", 0.4). 11 | addE("created").from("josh").to("ripple").property("weight", 1.0). 12 | addE("created").from("josh").to("lop").property("weight", 0.4). 13 | addE("created").from("peter").to("lop").property("weight", 0.2). 14 | addE("uses").from("peter").to("ripple").property("weight", 0.5).iterate() -------------------------------------------------------------------------------- /traversal-builder/src/main/resources/graph.txt: -------------------------------------------------------------------------------- 1 | +---------------------+ 2 | +------------------------------------| knows (weight: 1.0) |------------------------------------+ 3 | | +---------------------+ | 4 | | v 5 | +--------------+ +-------------+ +-------------+ 6 | | person | | software | | person | 7 | |--------------| +-----------------------+ |-------------| +-----------------------+ |-------------| 8 | | name | marko |---| created (weight: 0.4) |--->| name | lop |<---| created (weight: 0.4) |---| name | josh | 9 | | age | 29 | +-----------------------+ | lang | java | +-----------------------+ | age | 32 | 10 | +--------------+ +-------------+ +-------------+ 11 | | ^ | 12 | | | | 13 | +---------------------+ +-----------------------+ +---------------------+ 14 | | knows (weight: 0.5) | | created (weight: 0.2) | | knows (weight: 1.0) | 15 | +---------------------+ +-----------------------+ +---------------------+ 16 | | | | 17 | v | v 18 | +--------------+ +--------------+ +---------------+ 19 | | person | | person | | software | 20 | |--------------| |--------------| +--------------------+ |---------------| 21 | | name | vadas | | name | peter |----| uses (weight: 0.5) |--->| name | ripple | 22 | | age | 27 | | age | 35 | +--------------------+ | lang | java | 23 | +--------------+ +--------------+ +---------------+ -------------------------------------------------------------------------------- /traversal-builder/src/main/resources/schema.groovy: -------------------------------------------------------------------------------- 1 | schema.config().option("graph.allow_scan").set(true) 2 | 3 | schema.propertyKey("name").Text().single().ifNotExists().create() 4 | schema.propertyKey("age").Int().single().ifNotExists().create() 5 | schema.propertyKey("lang").Text().single().ifNotExists().create() 6 | schema.propertyKey("weight").Decimal().single().ifNotExists().create() 7 | 8 | schema.vertexLabel("person").partitionKey("name").properties("name","age").ifNotExists().create() 9 | schema.vertexLabel("software").partitionKey("name").properties("name","lang").ifNotExists().create() 10 | 11 | schema.edgeLabel("knows").single().properties("weight").ifNotExists().create() 12 | schema.edgeLabel("knows").connection("person","person").add() 13 | 14 | schema.edgeLabel("created").single().properties("weight").ifNotExists().create() 15 | schema.edgeLabel("created").connection("person","software").add() 16 | 17 | schema.edgeLabel("uses").single().properties("weight").ifNotExists().create() 18 | schema.edgeLabel("uses").connection("person","software").add() --------------------------------------------------------------------------------