├── README.md ├── datagen └── README.txt ├── neo4j ├── README.txt ├── bi_1.py ├── bi_10.py ├── bi_11.py ├── bi_12.py ├── bi_13.py ├── bi_14.py ├── bi_15.py ├── bi_16.py ├── bi_17.py ├── bi_18.py ├── bi_19.py ├── bi_2.py ├── bi_20.py ├── bi_21.py ├── bi_22.py ├── bi_23.py ├── bi_24.py ├── bi_25.py ├── bi_3.py ├── bi_4.py ├── bi_5.py ├── bi_6.py ├── bi_7.py ├── bi_8.py ├── bi_9.py ├── config.py ├── convert-csvs.sh ├── covert-data.sh ├── cypher-shell.sh ├── delete-neo4j-database.sh ├── header-remove.sh ├── how.sh ├── i_complex_1.py ├── i_complex_10.py ├── i_complex_11.py ├── i_complex_12.py ├── i_complex_13.py ├── i_complex_14.py ├── i_complex_2.py ├── i_complex_3.py ├── i_complex_4.py ├── i_complex_5.py ├── i_complex_6.py ├── i_complex_7.py ├── i_complex_8.py ├── i_complex_9.py ├── i_short_1.py ├── i_short_2.py ├── i_short_3.py ├── i_short_4.py ├── i_short_5.py ├── i_short_6.py ├── i_short_7.py ├── import-to-neo4j.sh ├── index_time.sh ├── load-coverted.sh ├── load-in-one-step.sh ├── load_scripts │ ├── README.txt │ ├── convert-data.sh │ ├── delete-neo4j-database.sh │ ├── headers.txt │ ├── import-to-neo4j.sh │ ├── index │ │ ├── drop-index-ldbc.cql │ │ ├── index-ldbc.cql │ │ ├── index-show.cql │ │ └── index_time.sh │ ├── load-coverted.sh │ ├── load-in-one-step.sh │ ├── path.sh │ ├── restart-neo4j.sh │ └── show-size.sh ├── path.sh ├── path_neo4j.sh ├── queries │ ├── bi-1.cypher │ ├── bi-10-without-pattern-comprehension.cypher │ ├── bi-10.cypher │ ├── bi-11.cypher │ ├── bi-12.cypher │ ├── bi-13.cypher │ ├── bi-14.cypher │ ├── bi-15.cypher │ ├── bi-16.cypher │ ├── bi-17.cypher │ ├── bi-18.cypher │ ├── bi-19.cypher │ ├── bi-2.cypher │ ├── bi-20.cypher │ ├── bi-21.cypher │ ├── bi-22.cypher │ ├── bi-23.cypher │ ├── bi-24.cypher │ ├── bi-25.cypher │ ├── bi-3.cypher │ ├── bi-4.cypher │ ├── bi-5.cypher │ ├── bi-6.cypher │ ├── bi-7.cypher │ ├── bi-8.cypher │ ├── bi-9.cypher │ ├── fix-query │ │ ├── bi-1.cypher │ │ ├── bi-10-without-pattern-comprehension.cypher │ │ ├── bi-10.cypher │ │ ├── bi-11.cypher │ │ ├── bi-12.cypher │ │ ├── bi-13.cypher │ │ ├── bi-14.cypher │ │ ├── bi-15.cypher │ │ ├── bi-16.cypher │ │ ├── bi-17.cypher │ │ ├── bi-18.cypher │ │ ├── bi-19.cypher │ │ ├── bi-2.cypher │ │ ├── bi-20.cypher │ │ ├── bi-21.cypher │ │ ├── bi-22.cypher │ │ ├── bi-23.cypher │ │ ├── bi-24.cypher │ │ ├── bi-25.cypher │ │ ├── bi-3.cypher │ │ ├── bi-4.cypher │ │ ├── bi-5.cypher │ │ ├── bi-6.cypher │ │ ├── bi-7.cypher │ │ ├── bi-8.cypher │ │ ├── bi-9.cypher │ │ ├── bi.sh │ │ ├── i-complex.sh │ │ ├── i-short.sh │ │ ├── interactive-complex-1.cypher │ │ ├── interactive-complex-10-without-list-comprehension.cypher │ │ ├── interactive-complex-10.cypher │ │ ├── interactive-complex-11.cypher │ │ ├── interactive-complex-12.cypher │ │ ├── interactive-complex-13.cypher │ │ ├── interactive-complex-14.cypher │ │ ├── interactive-complex-2.cypher │ │ ├── interactive-complex-3.cypher │ │ ├── interactive-complex-4.cypher │ │ ├── interactive-complex-5.cypher │ │ ├── interactive-complex-6.cypher │ │ ├── interactive-complex-7-with-lists.cypher │ │ ├── interactive-complex-7.cypher │ │ ├── interactive-complex-8.cypher │ │ ├── interactive-complex-9.cypher │ │ ├── interactive-short-1.cypher │ │ ├── interactive-short-2.cypher │ │ ├── interactive-short-3.cypher │ │ ├── interactive-short-4.cypher │ │ ├── interactive-short-5.cypher │ │ ├── interactive-short-6.cypher │ │ ├── interactive-short-7.cypher │ │ ├── interactive-update-1.cypher │ │ ├── interactive-update-2.cypher │ │ ├── interactive-update-3.cypher │ │ ├── interactive-update-4.cypher │ │ ├── interactive-update-5.cypher │ │ ├── interactive-update-6.cypher │ │ ├── interactive-update-7.cypher │ │ ├── interactive-update-8.cypher │ │ └── result │ │ │ ├── interactive-short-1.out │ │ │ ├── interactive-short-2.out │ │ │ ├── interactive-short-3.out │ │ │ ├── interactive-short-4.out │ │ │ ├── interactive-short-5.out │ │ │ ├── interactive-short-6.out │ │ │ ├── interactive-short-7.out │ │ │ └── time-interactive-short.out │ ├── interactive-complex-1.cypher │ ├── interactive-complex-10-without-list-comprehension.cypher │ ├── interactive-complex-10.cypher │ ├── interactive-complex-11.cypher │ ├── interactive-complex-12.cypher │ ├── interactive-complex-13.cypher │ ├── interactive-complex-14.cypher │ ├── interactive-complex-2.cypher │ ├── interactive-complex-3.cypher │ ├── interactive-complex-4.cypher │ ├── interactive-complex-5.cypher │ ├── interactive-complex-6.cypher │ ├── interactive-complex-7-with-lists.cypher │ ├── interactive-complex-7.cypher │ ├── interactive-complex-8.cypher │ ├── interactive-complex-9.cypher │ ├── interactive-short-1.cypher │ ├── interactive-short-2.cypher │ ├── interactive-short-3.cypher │ ├── interactive-short-4.cypher │ ├── interactive-short-5.cypher │ ├── interactive-short-6.cypher │ ├── interactive-short-7.cypher │ ├── interactive-update-1.cypher │ ├── interactive-update-2.cypher │ ├── interactive-update-3.cypher │ ├── interactive-update-4.cypher │ ├── interactive-update-5.cypher │ ├── interactive-update-6.cypher │ ├── interactive-update-7.cypher │ ├── interactive-update-8.cypher │ └── temp │ │ ├── bi-1.cypher │ │ ├── bi-10-without-pattern-comprehension.cypher │ │ ├── bi-10.cypher │ │ ├── bi-11.cypher │ │ ├── bi-12.cypher │ │ ├── bi-13.cypher │ │ ├── bi-14.cypher │ │ ├── bi-15.cypher │ │ ├── bi-16.cypher │ │ ├── bi-17.cypher │ │ ├── bi-18.cypher │ │ ├── bi-19.cypher │ │ ├── bi-2.cypher │ │ ├── bi-20.cypher │ │ ├── bi-21.cypher │ │ ├── bi-22.cypher │ │ ├── bi-23.cypher │ │ ├── bi-24.cypher │ │ ├── bi-25.cypher │ │ ├── bi-3.cypher │ │ ├── bi-4.cypher │ │ ├── bi-5.cypher │ │ ├── bi-6.cypher │ │ ├── bi-7.cypher │ │ ├── bi-8.cypher │ │ ├── bi-9.cypher │ │ ├── interactive-complex-1.cypher │ │ ├── interactive-complex-10-without-list-comprehension.cypher │ │ ├── interactive-complex-10.cypher │ │ ├── interactive-complex-11.cypher │ │ ├── interactive-complex-12.cypher │ │ ├── interactive-complex-13.cypher │ │ ├── interactive-complex-14.cypher │ │ ├── interactive-complex-2.cypher │ │ ├── interactive-complex-3.cypher │ │ ├── interactive-complex-4.cypher │ │ ├── interactive-complex-5.cypher │ │ ├── interactive-complex-6.cypher │ │ ├── interactive-complex-7-with-lists.cypher │ │ ├── interactive-complex-7.cypher │ │ ├── interactive-complex-8.cypher │ │ ├── interactive-complex-9.cypher │ │ ├── interactive-short-1.cypher │ │ ├── interactive-short-2.cypher │ │ ├── interactive-short-3.cypher │ │ ├── interactive-short-4.cypher │ │ ├── interactive-short-5.cypher │ │ ├── interactive-short-6.cypher │ │ ├── interactive-short-7.cypher │ │ ├── interactive-update-1.cypher │ │ ├── interactive-update-2.cypher │ │ ├── interactive-update-3.cypher │ │ ├── interactive-update-4.cypher │ │ ├── interactive-update-5.cypher │ │ ├── interactive-update-6.cypher │ │ ├── interactive-update-7.cypher │ │ └── interactive-update-8.cypher ├── query_runner.py ├── quick-switch.sh ├── restart-neo4j.sh ├── run.sh ├── run_all.sh ├── run_all_test.sh ├── run_bi.sh ├── run_bi_nodes.sh ├── run_i_complex.sh ├── run_i_short.sh ├── run_ic.sh ├── run_is.sh ├── run_node_1.sh ├── run_node_2.sh ├── run_node_3.sh ├── run_node_4.sh ├── run_node_5.sh ├── run_node_6.sh ├── run_node_7.sh ├── run_node_8.sh ├── run_node_all.sh ├── run_node_onepass.sh ├── show-size.sh ├── start.sh ├── stop.sh ├── switch.sh ├── warm_up.py └── which.sh ├── paper ├── DoWeNeedGraphDB.pdf ├── Introducing_the_graph_500.pdf ├── LDBC-Graphalytics_tech-specs_v0.9.0.pdf ├── TigerGraph evaluation V2.pdf ├── Tigergraph-benchmark-report.pdf ├── graph_database_ubiquity.pdf. ├── gsql_ddl_loading_v2.1.pdf ├── gsql_query_v2.1.pdf ├── ldbc-analytic.pdf ├── ldbc-snb-interactive-paper.pdf ├── ldbc-snb-specification.pdf └── ldbc_snb_bi_early_look.pdf └── tigergraph ├── README.txt ├── config.py ├── grestart.sh ├── gstop.sh ├── i_short_1.py ├── i_short_2.py ├── i_short_3.py ├── i_short_4.py ├── i_short_5.py ├── i_short_6.py ├── i_short_7.py ├── load_scripts ├── README.txt ├── SplitEdges ├── SplitEdges.cpp ├── SplitPlace ├── SplitPlace.cpp ├── convert_data.sh ├── convert_data_only.sh ├── load_data.sh ├── load_data_split.sh ├── load_data_split_time.sh ├── load_data_time.sh ├── load_in_one_step.sh ├── load_in_one_step_split.sh ├── path.sh ├── setup_schema.gsql ├── setup_schema_simple.gsql ├── setup_schema_split.gsql └── split_data.sh ├── queries ├── bi_.gsql ├── bi_1.gsql ├── bi_15.gsql ├── bi_17.gsql ├── bi_4.gsql ├── bi_5.gsql ├── bi_9.gsql ├── i_complex_.gsql ├── i_complex_13.gsql ├── i_complex_2.gsql ├── i_short_.gsql ├── i_short_1.gsql ├── i_short_2.gsql ├── i_short_3.gsql ├── i_short_4.gsql ├── i_short_5.gsql ├── i_short_6.gsql ├── i_short_7.gsql └── install.sh ├── query_runner.py └── run_i_short.sh /README.md: -------------------------------------------------------------------------------- 1 | # snb_benchmark -------------------------------------------------------------------------------- /datagen/README.txt: -------------------------------------------------------------------------------- 1 | Download ldbc_snb_datagen 2 | git clone https://github.com/ldbc/ldbc_snb_datagen 3 | 4 | Download Hadoop 5 | wget http://archive.apache.org/dist/hadoop/core/hadoop-2.6.0/hadoop-2.6.0.tar.gz 6 | tar xf hadoop-2.6.0.tar.gz 7 | 8 | ldbc_snb_datagen configuration 9 | In params-composite.ini, indentify size of data to generate. To generate SF=1 data: 10 | ldbc.snb.datagen.generator.scaleFactor:snb.interactive. 11 | 12 | In run.sh, set path and config 13 | export HADOOP_CLIENT_OPTS="-Xmx2G" 14 | export HADOOP_HOME=/path/to/hadoop/ 15 | export LDB_SNB_DATAGEN_HOME=/path/to/ldbc-snb-datagen 16 | 17 | In run.sh, modify line 21 from 18 | $HADOOP_HOME/bin/hadoop jar $LDBC_SNB_DATAGEN_HOME/target/ldbc_snb_datagen-0.2.7-jar-with-dependencies.jar $LDBC_SNB_DATAGEN_HOME/params.ini 19 | To 20 | $HADOOP_HOME/bin/hadoop jar $LDBC_SNB_DATAGEN_HOME/target/ldbc_snb_datagen-0.2.7-jar-with-dependencies.jar $LDBC_SNB_DATAGEN_HOME/params-composite.ini 21 | #With params-composite.ini, data column email and speaks will be populated into person_0_0.csv 22 | 23 | 24 | Generte data 25 | ./run.sh 26 | 27 | Note: assign a larger value to HADOOP_CLIENT_OPTS environment variable for larger data 28 | -------------------------------------------------------------------------------- /neo4j/bi_1.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_1(name_data, date, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_1" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_1(date) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = date 34 | line = name_data + "," + "bi_1," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_1," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_1.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_1.py snb_1 933 3 48 | run_bi_1(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_13.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_13(name_data, country, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_13" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_13(country) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = country 34 | line = name_data + "," + "bi_13," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_13," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_13.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_13.py snb_1 933 3 48 | run_bi_13(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_15.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_15(name_data, country, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_15" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_15(country) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = country 34 | line = name_data + "," + "bi_15," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_15," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_15.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_15.py snb_1 933 3 48 | run_bi_15(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_5.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_5(name_data, country, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_5" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_5(country) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = country 34 | line = name_data + "," + "bi_5," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_5," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_5.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_5.py snb_1 933 3 48 | run_bi_5(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_6.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_6(name_data, tag, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_6" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_6(tag) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = tag 34 | line = name_data + "," + "bi_6," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_6," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_6.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_6.py snb_1 933 3 48 | run_bi_6(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_7.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_7(name_data, tag, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_7" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_7(tag) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = tag 34 | line = name_data + "," + "bi_7," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_7," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_7.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_7.py snb_1 933 3 48 | run_bi_7(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/bi_8.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_bi_8(name_data, tag, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/bi_8" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | for i in range(0, num_tests): 28 | start = timer() 29 | runner.bi_8(tag) 30 | end = timer() 31 | exe_time = end - start 32 | total_time += exe_time 33 | query_param = tag 34 | line = name_data + "," + "bi_8," + str(i) + "," + query_param + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + name_data + "," + "bi_8," + query_param + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python bi_8.py name_data param num_tests") 46 | sys.exit() 47 | # python bi_8.py snb_1 933 3 48 | run_bi_8(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/config.py: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Copyright (c) 2015-now, Neo4j Inc. 3 | # All rights reserved 4 | # It is provided as it is for benchmark reproducible purpose. 5 | # anyone can use it for benchmark purpose with the 6 | # acknowledgement to Neo4j. 7 | # Author: Mingxi Wu mingxi.wu@tigergraph.com 8 | ############################################################ 9 | 10 | import os 11 | 12 | NEO4J_BOLT= os.environ.get("NEO4J_BOLT", "bolt://127.0.0.1:7687") 13 | TIGERGRAPH_HTTP = os.environ.get("TIGERGRAPH_HTTP", "http://127.0.0.1:9000") 14 | -------------------------------------------------------------------------------- /neo4j/convert-csvs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # replace headers 4 | while read line; do 5 | IFS=' ' read -r -a array <<< $line 6 | filename=${array[0]} 7 | header=${array[1]} 8 | sed -i "1s/.*/$header/" "${NEO4J_DATA_DIR}/${filename}${POSTFIX}" 9 | done < headers.txt 10 | 11 | ## replace labels with one starting with an uppercase letter 12 | sed -i "s/|city$/|City/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 13 | sed -i "s/|country$/|Country/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 14 | sed -i "s/|continent$/|Continent/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 15 | sed -i "s/|company|/|Company|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 16 | sed -i "s/|university|/|University|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 17 | # 18 | ## convert each date of format yyyy-mm-dd to a number of format yyyymmddd 19 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)|#|\1\2\3|#g" "${NEO4J_DATA_DIR}/person${POSTFIX}" 20 | # 21 | ## convert each datetime of format yyyy-mm-ddThh:mm:ss.mmm+0000 22 | ## to a number of format yyyymmddhhmmssmmm 23 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)T\([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)+0000#|\1\2\3\4\5\6\7#g" ${NEO4J_DATA_DIR}/*${POSTFIX} 24 | -------------------------------------------------------------------------------- /neo4j/covert-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # replace headers 4 | while read line; do 5 | IFS=' ' read -r -a array <<< $line 6 | filename=${array[0]} 7 | header=${array[1]} 8 | sed -i "1s/.*/$header/" "${NEO4J_DATA_DIR}/${filename}${POSTFIX}" 9 | done < headers.txt 10 | 11 | ## replace labels with one starting with an uppercase letter 12 | #sed -i "s/|city$/|City/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 13 | #sed -i "s/|country$/|Country/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 14 | #sed -i "s/|continent$/|Continent/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 15 | #sed -i "s/|company|/|Company|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 16 | #sed -i "s/|university|/|University|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 17 | # 18 | ## convert each date of format yyyy-mm-dd to a number of format yyyymmddd 19 | #sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)|#|\1\2\3|#g" "${NEO4J_DATA_DIR}/person${POSTFIX}" 20 | # 21 | ## convert each datetime of format yyyy-mm-ddThh:mm:ss.mmm+0000 22 | ## to a number of format yyyymmddhhmmssmmm 23 | #sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)T\([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)+0000#|\1\2\3\4\5\6\7#g" ${NEO4J_DATA_DIR}/*${POSTFIX} 24 | -------------------------------------------------------------------------------- /neo4j/cypher-shell.sh: -------------------------------------------------------------------------------- 1 | $NEO4J_HOME/bin/cypher-shell 2 | -------------------------------------------------------------------------------- /neo4j/delete-neo4j-database.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $NEO4J_HOME/bin/neo4j stop 4 | rm -rf $NEO4J_DB_DIR 5 | -------------------------------------------------------------------------------- /neo4j/header-remove.sh: -------------------------------------------------------------------------------- 1 | for filename in *.csv; do sed '1d' "${filename}" > ${filename}.tmp; done 2 | 3 | rm *.csv 4 | 5 | rename 's/.csv.tmp/.csv/g' * 6 | -------------------------------------------------------------------------------- /neo4j/how.sh: -------------------------------------------------------------------------------- 1 | . ./path_neo4j.sh 2 | $NEO4J_HOME/bin/neo4j status 3 | 4 | -------------------------------------------------------------------------------- /neo4j/i_short_1.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_1(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_1" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_1(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_1," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_1," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_1.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_1.py snb_1 933 3 48 | run_i_short_1(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_2.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_2(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_2" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_2(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_2," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_2," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_2.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_2.py snb_1 933 3 48 | run_i_short_2(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_3.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_3(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_3" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_3(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_3," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_3," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_3.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_3.py snb_1 933 3 48 | run_i_short_3(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_4.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_4(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_4" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_4(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_4," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_4," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_4.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_4.py snb_1 933 3 48 | run_i_short_4(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_5.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_5(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_5" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_5(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_5," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_5," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_5.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_5.py snb_1 933 3 48 | run_i_short_5(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_6.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_6(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_6" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_6(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_6," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_6," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_6.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_6.py snb_1 933 3 48 | run_i_short_6(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/i_short_7.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_7(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_7" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_7(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_7," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_7," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_7.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_7.py snb_1 933 3 48 | run_i_short_7(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /neo4j/index_time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ./path_neo4j.sh 3 | 4 | grep -n -r 'Index population started' $NEO4J_HOME/logs/debug.log > index-t0.out 5 | sed -i 's/[^0-9]//g' index-t0.out 6 | sed -i 's/^...//g' index-t0.out 7 | sed -i 's/......$//g' index-t0.out 8 | 9 | grep -n -r 'Index creation finished' $NEO4J_HOME/logs/debug.log > index-tn.out 10 | sed -i 's/[^0-9]//g' index-tn.out 11 | sed -i 's/^...//g' index-tn.out 12 | sed -i 's/......$//g' index-tn.out 13 | -------------------------------------------------------------------------------- /neo4j/load-coverted.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ./path.sh 3 | 4 | ./delete-neo4j-database.sh && ./import-to-neo4j.sh && ./restart-neo4j.sh 5 | 6 | ./show-size.sh 7 | -------------------------------------------------------------------------------- /neo4j/load-in-one-step.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #export NEO4J_HOME=/home/zhiyi/ecosys/neo4j-community-3.5.0 3 | #export NEO4J_DATA_DIR=/home/zhiyi/raw/snb/neo4j/social_network-1000 4 | #export NEO4J_DB_DIR=$NEO4J_HOME/data/databases/snb-1000.db 5 | #export POSTFIX=_0_0.csv 6 | 7 | . ./path.sh 8 | 9 | ./delete-neo4j-database.sh && ./convert-data.sh && ./import-to-neo4j.sh && ./restart-neo4j.sh 10 | 11 | ./show-size.sh 12 | -------------------------------------------------------------------------------- /neo4j/load_scripts/README.txt: -------------------------------------------------------------------------------- 1 | Modeofy path in path.sh 2 | . ./path.sh 3 | #set path to Neo4j install directory, Neo4j database directory, raw data directory 4 | 5 | ./convert-data.sh 6 | #replace headers with Neo4j-compatible ones 7 | #replace labels (e.g. change `city` to `City`) 8 | #convert date and datetime to integer formats 9 | 10 | 11 | ./delete-neo4j-database.sh 12 | ./import-to-neo4j.sh 13 | ./restart-neo4j.sh 14 | Delete Neo4j database and load the SNB raw data 15 | 16 | 17 | ./load-in-one-step.sh 18 | #execute convert-data.sh, delete-neo4j-database.sh, import-to-neo4j.sh, restart-neo4j.sh one by one 19 | -------------------------------------------------------------------------------- /neo4j/load_scripts/convert-data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # replace headers 4 | while read line; do 5 | IFS=' ' read -r -a array <<< $line 6 | filename=${array[0]} 7 | header=${array[1]} 8 | sed -i "1s/.*/$header/" "${NEO4J_DATA_DIR}/${filename}${POSTFIX}" 9 | done < headers.txt 10 | 11 | ## replace labels with one starting with an uppercase letter 12 | sed -i "s/|city$/|City/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 13 | sed -i "s/|country$/|Country/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 14 | sed -i "s/|continent$/|Continent/" "${NEO4J_DATA_DIR}/place${POSTFIX}" 15 | sed -i "s/|company|/|Company|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 16 | sed -i "s/|university|/|University|/" "${NEO4J_DATA_DIR}/organisation${POSTFIX}" 17 | # 18 | ## convert each date of format yyyy-mm-dd to a number of format yyyymmddd 19 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)|#|\1\2\3|#g" "${NEO4J_DATA_DIR}/person${POSTFIX}" 20 | # 21 | ## convert each datetime of format yyyy-mm-ddThh:mm:ss.mmm+0000 22 | ## to a number of format yyyymmddhhmmssmmm 23 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)T\([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)+0000#|\1\2\3\4\5\6\7#g" ${NEO4J_DATA_DIR}/*${POSTFIX} 24 | -------------------------------------------------------------------------------- /neo4j/load_scripts/delete-neo4j-database.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $NEO4J_HOME/bin/neo4j stop 4 | rm -rf $NEO4J_DB_DIR 5 | -------------------------------------------------------------------------------- /neo4j/load_scripts/index/drop-index-ldbc.cql: -------------------------------------------------------------------------------- 1 | DROP INDEX ON :Message(id); 2 | DROP INDEX ON :Comment(id); 3 | DROP INDEX ON :Forum(id); 4 | DROP INDEX ON :Organisation(id); 5 | DROP INDEX ON :Person(id); 6 | DROP INDEX ON :Place(name); 7 | DROP INDEX ON :Post(id); 8 | DROP INDEX ON :Tag(name); 9 | DROP INDEX ON :TagClass(name); 10 | -------------------------------------------------------------------------------- /neo4j/load_scripts/index/index-ldbc.cql: -------------------------------------------------------------------------------- 1 | CREATE INDEX ON :Message(id); 2 | CREATE INDEX ON :Comment(id); 3 | CREATE INDEX ON :Forum(id); 4 | CREATE INDEX ON :Organisation(id); 5 | CREATE INDEX ON :Person(id); 6 | CREATE INDEX ON :Place(name); 7 | CREATE INDEX ON :Post(id); 8 | CREATE INDEX ON :Tag(name); 9 | CREATE INDEX ON :TagClass(name); 10 | -------------------------------------------------------------------------------- /neo4j/load_scripts/index/index-show.cql: -------------------------------------------------------------------------------- 1 | call db.indexes; 2 | -------------------------------------------------------------------------------- /neo4j/load_scripts/index/index_time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ./path_neo4j.sh 3 | 4 | grep -n -r 'Index population started' $NEO4J_HOME/logs/debug.log > index-t0.out 5 | sed -i 's/[^0-9]//g' index-t0.out 6 | sed -i 's/^...//g' index-t0.out 7 | sed -i 's/......$//g' index-t0.out 8 | 9 | grep -n -r 'Index creation finished' $NEO4J_HOME/logs/debug.log > index-tn.out 10 | sed -i 's/[^0-9]//g' index-tn.out 11 | sed -i 's/^...//g' index-tn.out 12 | sed -i 's/......$//g' index-tn.out 13 | -------------------------------------------------------------------------------- /neo4j/load_scripts/load-coverted.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ./path.sh 3 | 4 | ./delete-neo4j-database.sh && ./import-to-neo4j.sh && ./restart-neo4j.sh 5 | 6 | ./show-size.sh 7 | -------------------------------------------------------------------------------- /neo4j/load_scripts/load-in-one-step.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #export NEO4J_HOME=/home/zhiyi/ecosys/neo4j-community-3.5.0 3 | #export NEO4J_DATA_DIR=/home/zhiyi/raw/snb/neo4j/social_network-1000 4 | #export NEO4J_DB_DIR=$NEO4J_HOME/data/databases/snb-1000.db 5 | #export POSTFIX=_0_0.csv 6 | 7 | . ./path.sh 8 | 9 | ./delete-neo4j-database.sh && ./convert-data.sh && ./import-to-neo4j.sh && ./restart-neo4j.sh 10 | 11 | ./show-size.sh 12 | -------------------------------------------------------------------------------- /neo4j/load_scripts/path.sh: -------------------------------------------------------------------------------- 1 | 2 | export NEO4J_HOME=/home/ubuntu/neo4j-community-3.5.0 3 | export NEO4J_DATA_DIR=/home/ubuntu/raw/neo4j/sf-1/social_network/ 4 | export NEO4J_DB_DIR=$NEO4J_HOME/data/databases/graph.db 5 | export POSTFIX=_0_0.csv 6 | -------------------------------------------------------------------------------- /neo4j/load_scripts/restart-neo4j.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $NEO4J_HOME/bin/neo4j restart 4 | -------------------------------------------------------------------------------- /neo4j/load_scripts/show-size.sh: -------------------------------------------------------------------------------- 1 | . ./path.sh 2 | du -sb $NEO4J_DB_DIR 3 | -------------------------------------------------------------------------------- /neo4j/path.sh: -------------------------------------------------------------------------------- 1 | 2 | export NEO4J_HOME=/home/ubuntu/neo4j-community-3.5.0 3 | export NEO4J_DATA_DIR=/home/ubuntu/raw/neo4j/sf-1/social_network/ 4 | export NEO4J_DB_DIR=$NEO4J_HOME/data/databases/graph.db 5 | export POSTFIX=_0_0.csv 6 | -------------------------------------------------------------------------------- /neo4j/path_neo4j.sh: -------------------------------------------------------------------------------- 1 | #export NEO4J_HOME=/home/zhiyi/ecosys/neo4j-community-3.5.0 2 | #export NEO4J_DB_DIR=$NEO4J_HOME/data/databases/graph.db 3 | 4 | echo NEO4J_HOME 5 | echo $NEO4J_HOME 6 | echo NEO4J_DB 7 | grep -E -o '.{0,10}neostore.counts.db.b' $NEO4J_DB_DIR/logs/debug.log 8 | 9 | -------------------------------------------------------------------------------- /neo4j/queries/bi-1.cypher: -------------------------------------------------------------------------------- 1 | // Q1. Posting summary 2 | /* 3 | :param { date: 20110721220000000 } 4 | */ 5 | MATCH (message:Message) 6 | WHERE message.creationDate < $date 7 | WITH count(message) AS totalMessageCountInt // this should be a subquery once Cypher supports it 8 | WITH toFloat(totalMessageCountInt) AS totalMessageCount 9 | MATCH (message:Message) 10 | WHERE message.creationDate < $date 11 | AND message.content IS NOT NULL 12 | WITH 13 | totalMessageCount, 14 | message, 15 | message.creationDate/10000000000000 AS year 16 | WITH 17 | totalMessageCount, 18 | year, 19 | message:Comment AS isComment, 20 | CASE 21 | WHEN message.length < 40 THEN 0 22 | WHEN message.length < 80 THEN 1 23 | WHEN message.length < 160 THEN 2 24 | ELSE 3 25 | END AS lengthCategory, 26 | count(message) AS messageCount, 27 | floor(avg(message.length)) AS averageMessageLength, 28 | sum(message.length) AS sumMessageLength 29 | RETURN 30 | year, 31 | isComment, 32 | lengthCategory, 33 | messageCount, 34 | averageMessageLength, 35 | sumMessageLength, 36 | messageCount / totalMessageCount AS percentageOfMessages 37 | ORDER BY 38 | year DESC, 39 | isComment ASC, 40 | lengthCategory ASC 41 | -------------------------------------------------------------------------------- /neo4j/queries/bi-10.cypher: -------------------------------------------------------------------------------- 1 | // Q10. Central Person for a Tag 2 | /* 3 | :param { 4 | tag: 'John_Rhys-Davies', 5 | date: 20120122000000000 6 | } 7 | */ 8 | MATCH (tag:Tag {name: $tag}) 9 | // score 10 | OPTIONAL MATCH (tag)<-[interest:HAS_INTEREST]-(person:Person) 11 | WITH tag, collect(person) AS interestedPersons 12 | OPTIONAL MATCH (tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 13 | WHERE message.creationDate > $date 14 | WITH tag, interestedPersons + collect(person) AS persons 15 | UNWIND persons AS person 16 | // poor man's disjunct union (should be changed to UNION + post-union processing in the future) 17 | WITH DISTINCT tag, person 18 | WITH 19 | tag, 20 | person, 21 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(person) | interest]) 22 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person) WHERE message.creationDate > $date | message]) 23 | AS score 24 | OPTIONAL MATCH (person)-[:KNOWS]-(friend) 25 | WITH 26 | person, 27 | score, 28 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(friend) | interest]) 29 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(friend) WHERE message.creationDate > $date | message]) 30 | AS friendScore 31 | RETURN 32 | person.id, 33 | score, 34 | sum(friendScore) AS friendsScore 35 | ORDER BY 36 | score + friendsScore DESC, 37 | person.id ASC 38 | LIMIT 100 39 | -------------------------------------------------------------------------------- /neo4j/queries/bi-11.cypher: -------------------------------------------------------------------------------- 1 | // Q11. Unrelated replies 2 | /* 3 | :param { 4 | country: 'Germany', 5 | blacklist: ['also', 'Pope', 'that', 'James', 'Henry', 'one', 'Green'] 6 | } 7 | */ 8 | WITH $blacklist AS blacklist 9 | MATCH 10 | (country:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 11 | (person:Person)<-[:HAS_CREATOR]-(reply:Comment)-[:REPLY_OF]->(message:Message), 12 | (reply)-[:HAS_TAG]->(tag:Tag) 13 | WHERE NOT (message)-[:HAS_TAG]->(:Tag)<-[:HAS_TAG]-(reply) 14 | AND size([word IN blacklist WHERE reply.content CONTAINS word | word]) = 0 15 | OPTIONAL MATCH 16 | (:Person)-[like:LIKES]->(reply) 17 | RETURN 18 | person.id, 19 | tag.name, 20 | count(DISTINCT like) AS countLikes, 21 | count(DISTINCT reply) AS countReplies 22 | ORDER BY 23 | countLikes DESC, 24 | person.id ASC, 25 | tag.name ASC 26 | LIMIT 100 27 | -------------------------------------------------------------------------------- /neo4j/queries/bi-12.cypher: -------------------------------------------------------------------------------- 1 | // Q12. Trending Posts 2 | /* 3 | :param { 4 | date: 20110721220000000, 5 | likeThreshold: 400 6 | } 7 | */ 8 | MATCH 9 | (message:Message)-[:HAS_CREATOR]->(creator:Person), 10 | (message)<-[like:LIKES]-(:Person) 11 | WHERE message.creationDate > $date 12 | WITH message, creator, count(like) AS likeCount 13 | WHERE likeCount > $likeThreshold 14 | RETURN 15 | message.id, 16 | message.creationDate, 17 | creator.firstName, 18 | creator.lastName, 19 | likeCount 20 | ORDER BY 21 | likeCount DESC, 22 | message.id ASC 23 | LIMIT 100 24 | -------------------------------------------------------------------------------- /neo4j/queries/bi-13.cypher: -------------------------------------------------------------------------------- 1 | // Q13. Popular Tags per month in a country 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH (:Country {name: $country})<-[:IS_LOCATED_IN]-(message:Message) 6 | OPTIONAL MATCH (message)-[:HAS_TAG]->(tag:Tag) 7 | WITH 8 | message.creationDate/10000000000000 AS year, 9 | message.creationDate/100000000000%100 AS month, 10 | message, 11 | tag 12 | WITH year, month, count(message) AS popularity, tag 13 | ORDER BY popularity DESC, tag.name ASC 14 | WITH 15 | year, 16 | month, 17 | collect([tag.name, popularity]) AS popularTags 18 | WITH 19 | year, 20 | month, 21 | [popularTag IN popularTags WHERE popularTag[0] IS NOT NULL] AS popularTags 22 | RETURN 23 | year, 24 | month, 25 | popularTags[0..5] AS topPopularTags 26 | ORDER BY 27 | year DESC, 28 | month ASC 29 | LIMIT 100 30 | -------------------------------------------------------------------------------- /neo4j/queries/bi-14.cypher: -------------------------------------------------------------------------------- 1 | // Q14. Top thread initiators 2 | /* 3 | :param { 4 | startDate: 20120531220000000, 5 | endDate: 20120630220000000 6 | } 7 | */ 8 | MATCH (person:Person)<-[:HAS_CREATOR]-(post:Post)<-[:REPLY_OF*0..]-(reply:Message) 9 | WHERE post.creationDate >= $startDate 10 | AND post.creationDate <= $endDate 11 | AND reply.creationDate >= $startDate 12 | AND reply.creationDate <= $endDate 13 | RETURN 14 | person.id, 15 | person.firstName, 16 | person.lastName, 17 | count(DISTINCT post) AS threadCount, 18 | count(DISTINCT reply) AS messageCount 19 | ORDER BY 20 | messageCount DESC, 21 | person.id ASC 22 | LIMIT 100 23 | -------------------------------------------------------------------------------- /neo4j/queries/bi-15.cypher: -------------------------------------------------------------------------------- 1 | // Q15. Social normals 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH 6 | (country:Country {name: $country}) 7 | MATCH 8 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person1:Person) 9 | OPTIONAL MATCH 10 | // start a new MATCH as friend might live in the same City 11 | // and thus can reuse the IS_PART_OF edge 12 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend1:Person), 13 | (person1)-[:KNOWS]-(friend1) 14 | WITH country, person1, count(friend1) AS friend1Count 15 | WITH country, avg(friend1Count) AS socialNormalFloat 16 | WITH country, floor(socialNormalFloat) AS socialNormal 17 | MATCH 18 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person2:Person) 19 | OPTIONAL MATCH 20 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend2:Person)-[:KNOWS]-(person2) 21 | WITH country, person2, count(friend2) AS friend2Count, socialNormal 22 | WHERE friend2Count = socialNormal 23 | RETURN 24 | person2.id, 25 | friend2Count AS count 26 | ORDER BY 27 | person2.id ASC 28 | LIMIT 100 29 | -------------------------------------------------------------------------------- /neo4j/queries/bi-16.cypher: -------------------------------------------------------------------------------- 1 | // Q16. Experts in social circle 2 | /* 3 | :param { 4 | personId: 19791209310731, 5 | country: 'Pakistan', 6 | tagClass: 'MusicalArtist', 7 | minPathDistance: 3, 8 | maxPathDistance: 5 9 | } 10 | */ 11 | // This query will not work in a browser as is. I tried alternatives approaches, 12 | // e.g. enabling path of arbitrary lengths, saving the path to a variable p and 13 | // checking for `$minPathDistance <= length(p)`, but these could not be 14 | // evaluated due to the excessive amount of paths. 15 | // If you would like to test the query in the browser, replace the values of 16 | // $minPathDistance and $maxPathDistance to a constant. 17 | MATCH 18 | (:Person {id: $personId})-[:KNOWS*$minPathDistance..$maxPathDistance]-(person:Person) 19 | WITH DISTINCT person 20 | MATCH 21 | (person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(:Country {name: $country}), 22 | (person)<-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]-> 23 | (:TagClass {name: $tagClass}) 24 | MATCH 25 | (message)-[:HAS_TAG]->(tag:Tag) 26 | RETURN 27 | person.id, 28 | tag.name, 29 | count(DISTINCT message) AS messageCount 30 | ORDER BY 31 | messageCount DESC, 32 | tag.name ASC, 33 | person.id ASC 34 | LIMIT 100 35 | -------------------------------------------------------------------------------- /neo4j/queries/bi-17.cypher: -------------------------------------------------------------------------------- 1 | // Q17. Friend triangles 2 | /* 3 | :param { country: 'Spain' } 4 | */ 5 | MATCH (country:Country {name: $country}) 6 | MATCH (a:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 7 | MATCH (b:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 8 | MATCH (c:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 9 | MATCH (a)-[:KNOWS]-(b), (b)-[:KNOWS]-(c), (c)-[:KNOWS]-(a) 10 | WHERE a.id < b.id 11 | AND b.id < c.id 12 | RETURN count(*) AS count 13 | // as a less elegant solution, count(a) also works 14 | -------------------------------------------------------------------------------- /neo4j/queries/bi-18.cypher: -------------------------------------------------------------------------------- 1 | // Q18. How many persons have a given number of posts 2 | /* 3 | :param { 4 | date: 20110722000000000, 5 | lengthThreshold: 20, 6 | languages: ['ar'] 7 | } 8 | */ 9 | MATCH (person:Person) 10 | OPTIONAL MATCH (person)<-[:HAS_CREATOR]-(message:Message)-[:REPLY_OF*0..]->(post:Post) 11 | WHERE message.content IS NOT NULL 12 | AND message.length < $lengthThreshold 13 | AND message.creationDate > $date 14 | AND post.language IN $languages 15 | WITH 16 | person, 17 | count(message) AS messageCount 18 | RETURN 19 | messageCount, 20 | count(person) AS personCount 21 | ORDER BY 22 | personCount DESC, 23 | messageCount DESC 24 | -------------------------------------------------------------------------------- /neo4j/queries/bi-19.cypher: -------------------------------------------------------------------------------- 1 | // Q19. Stranger's interaction 2 | /* 3 | :param { 4 | date: 19890101, 5 | tagClass1: 'MusicalArtist', 6 | tagClass2: 'OfficeHolder' 7 | } 8 | */ 9 | MATCH 10 | (:TagClass {name: $tagClass1})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 11 | (forum1:Forum)-[:HAS_MEMBER]->(stranger:Person) 12 | WITH DISTINCT stranger 13 | MATCH 14 | (:TagClass {name: $tagClass2})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 15 | (forum2:Forum)-[:HAS_MEMBER]->(stranger) 16 | WITH DISTINCT stranger 17 | MATCH 18 | (person:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF*]->(message:Message)-[:HAS_CREATOR]->(stranger) 19 | WHERE person.birthday > $date 20 | AND person <> stranger 21 | AND NOT (person)-[:KNOWS]-(stranger) 22 | AND NOT (message)-[:REPLY_OF*]->(:Message)-[:HAS_CREATOR]->(stranger) 23 | RETURN 24 | person.id, 25 | count(DISTINCT stranger) AS strangersCount, 26 | count(comment) AS interactionCount 27 | ORDER BY 28 | interactionCount DESC, 29 | person.id ASC 30 | LIMIT 100 31 | -------------------------------------------------------------------------------- /neo4j/queries/bi-2.cypher: -------------------------------------------------------------------------------- 1 | // Q2. Top tags for country, age, gender, time 2 | /* 3 | :param { 4 | date1: 20091231230000000, 5 | date2: 20101107230000000, 6 | country1: 'Ethiopia', 7 | country2: 'Belarus' 8 | } 9 | */ 10 | MATCH 11 | (country:Country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person:Person) 12 | <-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(tag:Tag) 13 | WHERE message.creationDate >= $startDate 14 | AND message.creationDate <= $endDate 15 | AND (country.name = $country1 OR country.name = $country2) 16 | WITH 17 | country.name AS countryName, 18 | message.creationDate/100000000000%100 AS month, 19 | person.gender AS gender, 20 | floor((20130101 - person.birthday) / 10000 / 5.0) AS ageGroup, 21 | tag.name AS tagName, 22 | message 23 | WITH 24 | countryName, month, gender, ageGroup, tagName, count(message) AS messageCount 25 | WHERE messageCount > 100 26 | RETURN 27 | countryName, 28 | month, 29 | gender, 30 | ageGroup, 31 | tagName, 32 | messageCount 33 | ORDER BY 34 | messageCount DESC, 35 | tagName ASC, 36 | ageGroup ASC, 37 | gender ASC, 38 | month ASC, 39 | countryName ASC 40 | LIMIT 100 41 | -------------------------------------------------------------------------------- /neo4j/queries/bi-20.cypher: -------------------------------------------------------------------------------- 1 | // Q20. High-level topics 2 | /* 3 | :param { tagClasses: ['Writer', 'Single', 'Country'] } 4 | */ 5 | UNWIND $tagClasses AS tagClassName 6 | MATCH 7 | (tagClass:TagClass {name: tagClassName})<-[:IS_SUBCLASS_OF*0..]- 8 | (:TagClass)<-[:HAS_TYPE]-(tag:Tag)<-[:HAS_TAG]-(message:Message) 9 | RETURN 10 | tagClass.name, 11 | count(DISTINCT message) AS messageCount 12 | ORDER BY 13 | messageCount DESC, 14 | tagClass.name ASC 15 | LIMIT 100 16 | -------------------------------------------------------------------------------- /neo4j/queries/bi-23.cypher: -------------------------------------------------------------------------------- 1 | // Q23. Holiday destinations 2 | /* 3 | :param { country: 'Egypt' } 4 | */ 5 | MATCH 6 | (home:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (:Person)<-[:HAS_CREATOR]-(message:Message)-[:IS_LOCATED_IN]->(destination:Country) 8 | WHERE home <> destination 9 | WITH 10 | message, 11 | destination, 12 | message.creationDate/100000000000%100 AS month 13 | RETURN 14 | count(message) AS messageCount, 15 | destination.name, 16 | month 17 | ORDER BY 18 | messageCount DESC, 19 | destination.name ASC, 20 | month ASC 21 | LIMIT 100 22 | -------------------------------------------------------------------------------- /neo4j/queries/bi-24.cypher: -------------------------------------------------------------------------------- 1 | // Q24. Messages by Topic and Continent 2 | /* 3 | :param { tagClass: 'Single' } 4 | */ 5 | MATCH (:TagClass {name: $tagClass})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]-(message:Message) 6 | WITH DISTINCT message 7 | MATCH (message)-[:IS_LOCATED_IN]->(:Country)-[:IS_PART_OF]->(continent:Continent) 8 | OPTIONAL MATCH (message)<-[like:LIKES]-(:Person) 9 | WITH 10 | message, 11 | message.creationDate/10000000000000 AS year, 12 | message.creationDate/100000000000%100 AS month, 13 | like, 14 | continent 15 | RETURN 16 | count(DISTINCT message) AS messageCount, 17 | count(like) AS likeCount, 18 | year, 19 | month, 20 | continent.name 21 | ORDER BY 22 | year ASC, 23 | month ASC, 24 | continent.name DESC 25 | LIMIT 100 26 | -------------------------------------------------------------------------------- /neo4j/queries/bi-3.cypher: -------------------------------------------------------------------------------- 1 | // Q3. Tag evolution 2 | /* 3 | :param { 4 | year: 2010, 5 | month: 10 6 | } 7 | */ 8 | WITH 9 | $year AS year1, 10 | $month AS month1, 11 | $year + toInteger($month / 12.0) AS year2, 12 | $month % 12 + 1 AS month2 13 | // year-month 1 14 | MATCH (tag:Tag) 15 | OPTIONAL MATCH (message1:Message)-[:HAS_TAG]->(tag) 16 | WHERE message1.creationDate/10000000000000 = year1 17 | AND message1.creationDate/100000000000%100 = month1 18 | WITH year2, month2, tag, count(message1) AS countMonth1 19 | // year-month 2 20 | OPTIONAL MATCH (message2:Message)-[:HAS_TAG]->(tag) 21 | WHERE message2.creationDate/10000000000000 = year2 22 | AND message2.creationDate/100000000000%100 = month2 23 | WITH 24 | tag, 25 | countMonth1, 26 | count(message2) AS countMonth2 27 | RETURN 28 | tag.name, 29 | countMonth1, 30 | countMonth2, 31 | abs(countMonth1-countMonth2) AS diff 32 | ORDER BY 33 | diff DESC, 34 | tag.name ASC 35 | LIMIT 100 36 | -------------------------------------------------------------------------------- /neo4j/queries/bi-4.cypher: -------------------------------------------------------------------------------- 1 | // Q4. Popular topics in a country 2 | /* 3 | :param { 4 | tagClass: 'MusicalArtist', 5 | country: 'Burma' 6 | } 7 | */ 8 | MATCH 9 | (:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 10 | (person:Person)<-[:HAS_MODERATOR]-(forum:Forum)-[:CONTAINER_OF]-> 11 | (post:Post)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass}) 12 | RETURN 13 | forum.id, 14 | forum.title, 15 | forum.creationDate, 16 | person.id, 17 | count(DISTINCT post) AS postCount 18 | ORDER BY 19 | postCount DESC, 20 | forum.id ASC 21 | LIMIT 20 -------------------------------------------------------------------------------- /neo4j/queries/bi-5.cypher: -------------------------------------------------------------------------------- 1 | // Q5. Top posters in a country 2 | /* 3 | :param { country: 'Belarus' } 4 | */ 5 | MATCH 6 | (:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (person:Person)<-[:HAS_MEMBER]-(forum:Forum) 8 | WITH forum, count(person) AS numberOfMembers 9 | ORDER BY numberOfMembers DESC, forum.id ASC 10 | LIMIT 100 11 | WITH collect(forum) AS popularForums 12 | UNWIND popularForums AS forum 13 | MATCH 14 | (forum)-[:HAS_MEMBER]->(person:Person) 15 | OPTIONAL MATCH 16 | (person)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(popularForum:Forum) 17 | WHERE popularForum IN popularForums 18 | RETURN 19 | person.id, 20 | person.firstName, 21 | person.lastName, 22 | person.creationDate, 23 | count(DISTINCT post) AS postCount 24 | ORDER BY 25 | postCount DESC, 26 | person.id ASC 27 | LIMIT 100 28 | -------------------------------------------------------------------------------- /neo4j/queries/bi-6.cypher: -------------------------------------------------------------------------------- 1 | // Q6. Most active Posters of a given Topic 2 | /* 3 | :param { tag: 'Abbas_I_of_Persia' } 4 | */ 5 | MATCH (tag:Tag {name: $tag})<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 6 | OPTIONAL MATCH (:Person)-[like:LIKES]->(message) 7 | OPTIONAL MATCH (message)<-[:REPLY_OF]-(comment:Comment) 8 | WITH person, count(DISTINCT like) AS likeCount, count(DISTINCT comment) AS replyCount, count(DISTINCT message) AS messageCount 9 | RETURN 10 | person.id, 11 | replyCount, 12 | likeCount, 13 | messageCount, 14 | 1*messageCount + 2*replyCount + 10*likeCount AS score 15 | ORDER BY 16 | score DESC, 17 | person.id ASC 18 | LIMIT 100 19 | -------------------------------------------------------------------------------- /neo4j/queries/bi-7.cypher: -------------------------------------------------------------------------------- 1 | // Q7. Most authoritative users on a given topic 2 | /* 3 | :param { tag: 'Arnold_Schwarzenegger' } 4 | */ 5 | MATCH (tag:Tag {name: $tag}) 6 | MATCH (tag)<-[:HAS_TAG]-(message1:Message)-[:HAS_CREATOR]->(person1:Person) 7 | MATCH (tag)<-[:HAS_TAG]-(message2:Message)-[:HAS_CREATOR]->(person1) 8 | OPTIONAL MATCH (message2)<-[:LIKES]-(person2:Person) 9 | OPTIONAL MATCH (person2)<-[:HAS_CREATOR]-(message3:Message)<-[like:LIKES]-(p3:Person) 10 | RETURN 11 | person1.id, 12 | count(DISTINCT like) AS authorityScore 13 | ORDER BY 14 | authorityScore DESC, 15 | person1.id ASC 16 | LIMIT 100 17 | -------------------------------------------------------------------------------- /neo4j/queries/bi-8.cypher: -------------------------------------------------------------------------------- 1 | // Q8. Related Topics 2 | /* 3 | :param { tag: 'Genghis_Khan' } 4 | */ 5 | MATCH 6 | (tag:Tag {name: $tag})<-[:HAS_TAG]-(message:Message), 7 | (message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_TAG]->(relatedTag:Tag) 8 | WHERE NOT (comment)-[:HAS_TAG]->(tag) 9 | RETURN 10 | relatedTag.name, 11 | count(DISTINCT comment) AS count 12 | ORDER BY 13 | count DESC, 14 | relatedTag.name ASC 15 | LIMIT 100 16 | -------------------------------------------------------------------------------- /neo4j/queries/bi-9.cypher: -------------------------------------------------------------------------------- 1 | // Q9. Forum with related Tags 2 | /* 3 | :param { 4 | tagClass1: 'BaseballPlayer', 5 | tagClass2: 'ChristianBishop', 6 | threshold: 200 7 | } 8 | */ 9 | MATCH 10 | (forum:Forum)-[:HAS_MEMBER]->(person:Person) 11 | WITH forum, count(person) AS members 12 | WHERE members > $threshold 13 | MATCH 14 | (forum)-[:CONTAINER_OF]->(post1:Post)-[:HAS_TAG]-> 15 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass1}) 16 | WITH forum, count(DISTINCT post1) AS count1 17 | MATCH 18 | (forum)-[:CONTAINER_OF]->(post2:Post)-[:HAS_TAG]-> 19 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass2}) 20 | WITH forum, count1, count(DISTINCT post2) AS count2 21 | RETURN 22 | forum.id, 23 | count1, 24 | count2 25 | ORDER BY 26 | abs(count2-count1) DESC, 27 | forum.id ASC 28 | LIMIT 100 29 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-1.cypher: -------------------------------------------------------------------------------- 1 | // Q1. Posting summary 2 | /* 3 | :param { date: 20110721220000000 } 4 | */ 5 | MATCH (message:Message) 6 | WHERE message.creationDate < 20110721220000000 7 | WITH count(message) AS totalMessageCountInt // this should be a subquery once Cypher supports it 8 | WITH toFloat(totalMessageCountInt) AS totalMessageCount 9 | MATCH (message:Message) 10 | WHERE message.creationDate < 20110721220000000 11 | AND message.content IS NOT NULL 12 | WITH 13 | totalMessageCount, 14 | message, 15 | message.creationDate/10000000000000 AS year 16 | WITH 17 | totalMessageCount, 18 | year, 19 | message:Comment AS isComment, 20 | CASE 21 | WHEN message.length < 40 THEN 0 22 | WHEN message.length < 80 THEN 1 23 | WHEN message.length < 160 THEN 2 24 | ELSE 3 25 | END AS lengthCategory, 26 | count(message) AS messageCount, 27 | floor(avg(message.length)) AS averageMessageLength, 28 | sum(message.length) AS sumMessageLength 29 | RETURN 30 | year, 31 | isComment, 32 | lengthCategory, 33 | messageCount, 34 | averageMessageLength, 35 | sumMessageLength, 36 | messageCount / totalMessageCount AS percentageOfMessages 37 | ORDER BY 38 | year DESC, 39 | isComment ASC, 40 | lengthCategory ASC; 41 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-10.cypher: -------------------------------------------------------------------------------- 1 | // Q10. Central Person for a Tag 2 | /* 3 | :param { 4 | tag: 'John_Rhys-Davies', 5 | date: 20120122000000000 6 | } 7 | */ 8 | MATCH (tag:Tag {name: 'John_Rhys-Davies'}) 9 | // score 10 | OPTIONAL MATCH (tag)<-[interest:HAS_INTEREST]-(person:Person) 11 | WITH tag, collect(person) AS interestedPersons 12 | OPTIONAL MATCH (tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 13 | WHERE message.creationDate > 20120122000000000 14 | WITH tag, interestedPersons + collect(person) AS persons 15 | UNWIND persons AS person 16 | // poor man's disjunct union (should be changed to UNION + post-union processing in the future) 17 | WITH DISTINCT tag, person 18 | WITH 19 | tag, 20 | person, 21 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(person) | interest]) 22 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person) WHERE message.creationDate > 20120122000000000 | message]) 23 | AS score 24 | OPTIONAL MATCH (person)-[:KNOWS]-(friend) 25 | WITH 26 | person, 27 | score, 28 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(friend) | interest]) 29 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(friend) WHERE message.creationDate > 20120122000000000 | message]) 30 | AS friendScore 31 | RETURN 32 | person.id, 33 | score, 34 | sum(friendScore) AS friendsScore 35 | ORDER BY 36 | score + friendsScore DESC, 37 | person.id ASC 38 | LIMIT 100; 39 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-11.cypher: -------------------------------------------------------------------------------- 1 | // Q11. Unrelated replies 2 | /* 3 | :param { 4 | country: 'Germany', 5 | blacklist: ['also', 'Pope', 'that', 'James', 'Henry', 'one', 'Green'] 6 | } 7 | */ 8 | WITH ['also', 'Pope', 'that', 'James', 'Henry', 'one', 'Green'] AS blacklist 9 | MATCH 10 | (country:Country {name: 'Germany'})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 11 | (person:Person)<-[:HAS_CREATOR]-(reply:Comment)-[:REPLY_OF]->(message:Message), 12 | (reply)-[:HAS_TAG]->(tag:Tag) 13 | WHERE NOT (message)-[:HAS_TAG]->(:Tag)<-[:HAS_TAG]-(reply) 14 | AND size([word IN blacklist WHERE reply.content CONTAINS word | word]) = 0 15 | OPTIONAL MATCH 16 | (:Person)-[like:LIKES]->(reply) 17 | RETURN 18 | person.id, 19 | tag.name, 20 | count(DISTINCT like) AS countLikes, 21 | count(DISTINCT reply) AS countReplies 22 | ORDER BY 23 | countLikes DESC, 24 | person.id ASC, 25 | tag.name ASC 26 | LIMIT 100; 27 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-12.cypher: -------------------------------------------------------------------------------- 1 | // Q12. Trending Posts 2 | /* 3 | :param { 4 | date: 20110721220000000, 5 | likeThreshold: 400 6 | } 7 | */ 8 | MATCH 9 | (message:Message)-[:HAS_CREATOR]->(creator:Person), 10 | (message)<-[like:LIKES]-(:Person) 11 | WHERE message.creationDate > 20110721220000000 12 | WITH message, creator, count(like) AS likeCount 13 | WHERE likeCount > 400 14 | RETURN 15 | message.id, 16 | message.creationDate, 17 | creator.firstName, 18 | creator.lastName, 19 | likeCount 20 | ORDER BY 21 | likeCount DESC, 22 | message.id ASC 23 | LIMIT 100; 24 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-13.cypher: -------------------------------------------------------------------------------- 1 | // Q13. Popular Tags per month in a country 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH (:Country {name: 'Burma'})<-[:IS_LOCATED_IN]-(message:Message) 6 | OPTIONAL MATCH (message)-[:HAS_TAG]->(tag:Tag) 7 | WITH 8 | message.creationDate/10000000000000 AS year, 9 | message.creationDate/100000000000%100 AS month, 10 | message, 11 | tag 12 | WITH year, month, count(message) AS popularity, tag 13 | ORDER BY popularity DESC, tag.name ASC 14 | WITH 15 | year, 16 | month, 17 | collect([tag.name, popularity]) AS popularTags 18 | WITH 19 | year, 20 | month, 21 | [popularTag IN popularTags WHERE popularTag[0] IS NOT NULL] AS popularTags 22 | RETURN 23 | year, 24 | month, 25 | popularTags[0..5] AS topPopularTags 26 | ORDER BY 27 | year DESC, 28 | month ASC 29 | LIMIT 100; 30 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-14.cypher: -------------------------------------------------------------------------------- 1 | // Q14. Top thread initiators 2 | /* 3 | :param { 4 | startDate: 20120531220000000, 5 | endDate: 20120630220000000 6 | } 7 | */ 8 | MATCH (person:Person)<-[:HAS_CREATOR]-(post:Post)<-[:REPLY_OF*0..]-(reply:Message) 9 | WHERE post.creationDate >= 20120531220000000 10 | AND post.creationDate <= 20120630220000000 11 | AND reply.creationDate >= 20120531220000000 12 | AND reply.creationDate <= 20120630220000000 13 | RETURN 14 | person.id, 15 | person.firstName, 16 | person.lastName, 17 | count(DISTINCT post) AS threadCount, 18 | count(DISTINCT reply) AS messageCount 19 | ORDER BY 20 | messageCount DESC, 21 | person.id ASC 22 | LIMIT 100; 23 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-15.cypher: -------------------------------------------------------------------------------- 1 | // Q15. Social normals 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH 6 | (country:Country {name: 'Burma'}) 7 | MATCH 8 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person1:Person) 9 | OPTIONAL MATCH 10 | // start a new MATCH as friend might live in the same City 11 | // and thus can reuse the IS_PART_OF edge 12 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend1:Person), 13 | (person1)-[:KNOWS]-(friend1) 14 | WITH country, person1, count(friend1) AS friend1Count 15 | WITH country, avg(friend1Count) AS socialNormalFloat 16 | WITH country, floor(socialNormalFloat) AS socialNormal 17 | MATCH 18 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person2:Person) 19 | OPTIONAL MATCH 20 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend2:Person)-[:KNOWS]-(person2) 21 | WITH country, person2, count(friend2) AS friend2Count, socialNormal 22 | WHERE friend2Count = socialNormal 23 | RETURN 24 | person2.id, 25 | friend2Count AS count 26 | ORDER BY 27 | person2.id ASC 28 | LIMIT 100 29 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-16.cypher: -------------------------------------------------------------------------------- 1 | // Q16. Experts in social circle 2 | /* 3 | :param { 4 | personId: 19791209310731, 5 | country: 'Pakistan', 6 | tagClass: 'MusicalArtist', 7 | minPathDistance: 3, 8 | maxPathDistance: 5 9 | } 10 | */ 11 | // This query will not work in a browser as is. I tried alternatives approaches, 12 | // e.g. enabling path of arbitrary lengths, saving the path to a variable p and 13 | // checking for `$minPathDistance <= length(p)`, but these could not be 14 | // evaluated due to the excessive amount of paths. 15 | // If you would like to test the query in the browser, replace the values of 16 | // $minPathDistance and $maxPathDistance to a constant. 17 | MATCH 18 | (:Person {id: 19791209310731})-[:KNOWS*3..5]-(person:Person) 19 | WITH DISTINCT person 20 | MATCH 21 | (person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(:Country {name: 'Pakistan'}), 22 | (person)<-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]-> 23 | (:TagClass {name: 'MusicalArtist'}) 24 | MATCH 25 | (message)-[:HAS_TAG]->(tag:Tag) 26 | RETURN 27 | person.id, 28 | tag.name, 29 | count(DISTINCT message) AS messageCount 30 | ORDER BY 31 | messageCount DESC, 32 | tag.name ASC, 33 | person.id ASC 34 | LIMIT 100; 35 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-17.cypher: -------------------------------------------------------------------------------- 1 | // Q17. Friend triangles 2 | /* 3 | :param { country: 'Spain' } 4 | */ 5 | MATCH (country:Country {name: 'Spain'}) 6 | MATCH (a:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 7 | MATCH (b:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 8 | MATCH (c:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 9 | MATCH (a)-[:KNOWS]-(b), (b)-[:KNOWS]-(c), (c)-[:KNOWS]-(a) 10 | WHERE a.id < b.id 11 | AND b.id < c.id 12 | RETURN count(*) AS count; 13 | // as a less elegant solution, count(a) also works 14 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-18.cypher: -------------------------------------------------------------------------------- 1 | // Q18. How many persons have a given number of posts 2 | /* 3 | :param { 4 | date: 20110722000000000, 5 | lengthThreshold: 20, 6 | languages: ['ar'] 7 | } 8 | */ 9 | MATCH (person:Person) 10 | OPTIONAL MATCH (person)<-[:HAS_CREATOR]-(message:Message)-[:REPLY_OF*0..]->(post:Post) 11 | WHERE message.content IS NOT NULL 12 | AND message.length < 20 13 | AND message.creationDate > 20110722000000000 14 | AND post.language IN ['ar'] 15 | WITH 16 | person, 17 | count(message) AS messageCount 18 | RETURN 19 | messageCount, 20 | count(person) AS personCount 21 | ORDER BY 22 | personCount DESC, 23 | messageCount DESC; 24 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-19.cypher: -------------------------------------------------------------------------------- 1 | // Q19. Stranger's interaction 2 | /* 3 | :param { 4 | date: 19890101, 5 | tagClass1: 'MusicalArtist', 6 | tagClass2: 'OfficeHolder' 7 | } 8 | */ 9 | MATCH 10 | (:TagClass {name: 'MusicalArtist'})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 11 | (forum1:Forum)-[:HAS_MEMBER]->(stranger:Person) 12 | WITH DISTINCT stranger 13 | MATCH 14 | (:TagClass {name: 'OfficeHolder'})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 15 | (forum2:Forum)-[:HAS_MEMBER]->(stranger) 16 | WITH DISTINCT stranger 17 | MATCH 18 | (person:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF*]->(message:Message)-[:HAS_CREATOR]->(stranger) 19 | WHERE person.birthday > 19890101 20 | AND person <> stranger 21 | AND NOT (person)-[:KNOWS]-(stranger) 22 | AND NOT (message)-[:REPLY_OF*]->(:Message)-[:HAS_CREATOR]->(stranger) 23 | RETURN 24 | person.id, 25 | count(DISTINCT stranger) AS strangersCount, 26 | count(comment) AS interactionCount 27 | ORDER BY 28 | interactionCount DESC, 29 | person.id ASC 30 | LIMIT 100 31 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-2.cypher: -------------------------------------------------------------------------------- 1 | // Q2. Top tags for country, age, gender, time 2 | /* 3 | :param { 4 | date1: 20091231230000000, 5 | date2: 20101107230000000, 6 | country1: 'Ethiopia', 7 | country2: 'Belarus' 8 | } 9 | */ 10 | MATCH 11 | (country:Country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person:Person) 12 | <-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(tag:Tag) 13 | WHERE message.creationDate >= 20091231230000000 14 | AND message.creationDate <= 20101107230000000 15 | AND (country.name = "Ethiopia" OR country.name = "Belarus") 16 | WITH 17 | country.name AS countryName, 18 | message.creationDate/100000000000%100 AS month, 19 | person.gender AS gender, 20 | floor((20130101 - person.birthday) / 10000 / 5.0) AS ageGroup, 21 | tag.name AS tagName, 22 | message 23 | WITH 24 | countryName, month, gender, ageGroup, tagName, count(message) AS messageCount 25 | WHERE messageCount > 100 26 | RETURN 27 | countryName, 28 | month, 29 | gender, 30 | ageGroup, 31 | tagName, 32 | messageCount 33 | ORDER BY 34 | messageCount DESC, 35 | tagName ASC, 36 | ageGroup ASC, 37 | gender ASC, 38 | month ASC, 39 | countryName ASC 40 | LIMIT 100; 41 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-20.cypher: -------------------------------------------------------------------------------- 1 | // Q20. High-level topics 2 | /* 3 | :param { tagClasses: ['Writer', 'Single', 'Country'] } 4 | */ 5 | UNWIND $tagClasses AS tagClassName 6 | MATCH 7 | (tagClass:TagClass {name: tagClassName})<-[:IS_SUBCLASS_OF*0..]- 8 | (:TagClass)<-[:HAS_TYPE]-(tag:Tag)<-[:HAS_TAG]-(message:Message) 9 | RETURN 10 | tagClass.name, 11 | count(DISTINCT message) AS messageCount 12 | ORDER BY 13 | messageCount DESC, 14 | tagClass.name ASC 15 | LIMIT 100 16 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-23.cypher: -------------------------------------------------------------------------------- 1 | // Q23. Holiday destinations 2 | /* 3 | :param { country: 'Egypt' } 4 | */ 5 | MATCH 6 | (home:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (:Person)<-[:HAS_CREATOR]-(message:Message)-[:IS_LOCATED_IN]->(destination:Country) 8 | WHERE home <> destination 9 | WITH 10 | message, 11 | destination, 12 | message.creationDate/100000000000%100 AS month 13 | RETURN 14 | count(message) AS messageCount, 15 | destination.name, 16 | month 17 | ORDER BY 18 | messageCount DESC, 19 | destination.name ASC, 20 | month ASC 21 | LIMIT 100 22 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-24.cypher: -------------------------------------------------------------------------------- 1 | // Q24. Messages by Topic and Continent 2 | /* 3 | :param { tagClass: 'Single' } 4 | */ 5 | MATCH (:TagClass {name: $tagClass})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]-(message:Message) 6 | WITH DISTINCT message 7 | MATCH (message)-[:IS_LOCATED_IN]->(:Country)-[:IS_PART_OF]->(continent:Continent) 8 | OPTIONAL MATCH (message)<-[like:LIKES]-(:Person) 9 | WITH 10 | message, 11 | message.creationDate/10000000000000 AS year, 12 | message.creationDate/100000000000%100 AS month, 13 | like, 14 | continent 15 | RETURN 16 | count(DISTINCT message) AS messageCount, 17 | count(like) AS likeCount, 18 | year, 19 | month, 20 | continent.name 21 | ORDER BY 22 | year ASC, 23 | month ASC, 24 | continent.name DESC 25 | LIMIT 100 26 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-3.cypher: -------------------------------------------------------------------------------- 1 | // Q3. Tag evolution 2 | /* 3 | :param { 4 | year: 2010, 5 | month: 10 6 | } 7 | */ 8 | WITH 9 | 2010 AS year1, 10 | 10 AS month1, 11 | 2010 + toInteger(10 / 12.0) AS year2, 12 | 10 % 12 + 1 AS month2 13 | // year-month 1 14 | MATCH (tag:Tag) 15 | OPTIONAL MATCH (message1:Message)-[:HAS_TAG]->(tag) 16 | WHERE message1.creationDate/10000000000000 = year1 17 | AND message1.creationDate/100000000000%100 = month1 18 | WITH year2, month2, tag, count(message1) AS countMonth1 19 | // year-month 2 20 | OPTIONAL MATCH (message2:Message)-[:HAS_TAG]->(tag) 21 | WHERE message2.creationDate/10000000000000 = year2 22 | AND message2.creationDate/100000000000%100 = month2 23 | WITH 24 | tag, 25 | countMonth1, 26 | count(message2) AS countMonth2 27 | RETURN 28 | tag.name, 29 | countMonth1, 30 | countMonth2, 31 | abs(countMonth1-countMonth2) AS diff 32 | ORDER BY 33 | diff DESC, 34 | tag.name ASC 35 | LIMIT 100; 36 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-4.cypher: -------------------------------------------------------------------------------- 1 | // Q4. Popular topics in a country 2 | /* 3 | :param { 4 | tagClass: 'MusicalArtist', 5 | country: 'Burma' 6 | } 7 | */ 8 | MATCH 9 | (:Country {name: 'Burma'})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 10 | (person:Person)<-[:HAS_MODERATOR]-(forum:Forum)-[:CONTAINER_OF]-> 11 | (post:Post)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]->(:TagClass {name: 'MusicalArtist'}) 12 | RETURN 13 | forum.id, 14 | forum.title, 15 | forum.creationDate, 16 | person.id, 17 | count(DISTINCT post) AS postCount 18 | ORDER BY 19 | postCount DESC, 20 | forum.id ASC 21 | LIMIT 2; 22 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-5.cypher: -------------------------------------------------------------------------------- 1 | // Q5. Top posters in a country 2 | /* 3 | :param { country: 'Belarus' } 4 | */ 5 | MATCH 6 | (:Country {name: 'Belarus'})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (person:Person)<-[:HAS_MEMBER]-(forum:Forum) 8 | WITH forum, count(person) AS numberOfMembers 9 | ORDER BY numberOfMembers DESC, forum.id ASC 10 | LIMIT 100 11 | WITH collect(forum) AS popularForums 12 | UNWIND popularForums AS forum 13 | MATCH 14 | (forum)-[:HAS_MEMBER]->(person:Person) 15 | OPTIONAL MATCH 16 | (person)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(popularForum:Forum) 17 | WHERE popularForum IN popularForums 18 | RETURN 19 | person.id, 20 | person.firstName, 21 | person.lastName, 22 | person.creationDate, 23 | count(DISTINCT post) AS postCount 24 | ORDER BY 25 | postCount DESC, 26 | person.id ASC 27 | LIMIT 100; 28 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-6.cypher: -------------------------------------------------------------------------------- 1 | // Q6. Most active Posters of a given Topic 2 | /* 3 | :param { tag: 'Abbas_I_of_Persia' } 4 | */ 5 | MATCH (tag:Tag {name: 'Abbas_I_of_Persia'})<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 6 | OPTIONAL MATCH (:Person)-[like:LIKES]->(message) 7 | OPTIONAL MATCH (message)<-[:REPLY_OF]-(comment:Comment) 8 | WITH person, count(DISTINCT like) AS likeCount, count(DISTINCT comment) AS replyCount, count(DISTINCT message) AS messageCount 9 | RETURN 10 | person.id, 11 | replyCount, 12 | likeCount, 13 | messageCount, 14 | 1*messageCount + 2*replyCount + 10*likeCount AS score 15 | ORDER BY 16 | score DESC, 17 | person.id ASC 18 | LIMIT 100; 19 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-7.cypher: -------------------------------------------------------------------------------- 1 | // Q7. Most authoritative users on a given topic 2 | /* 3 | :param { tag: 'Arnold_Schwarzenegger' } 4 | */ 5 | MATCH (tag:Tag {name: 'Arnold_Schwarzenegger'}) 6 | MATCH (tag)<-[:HAS_TAG]-(message1:Message)-[:HAS_CREATOR]->(person1:Person) 7 | MATCH (tag)<-[:HAS_TAG]-(message2:Message)-[:HAS_CREATOR]->(person1) 8 | OPTIONAL MATCH (message2)<-[:LIKES]-(person2:Person) 9 | OPTIONAL MATCH (person2)<-[:HAS_CREATOR]-(message3:Message)<-[like:LIKES]-(p3:Person) 10 | RETURN 11 | person1.id, 12 | count(DISTINCT like) AS authorityScore 13 | ORDER BY 14 | authorityScore DESC, 15 | person1.id ASC 16 | LIMIT 100; 17 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-8.cypher: -------------------------------------------------------------------------------- 1 | // Q8. Related Topics 2 | /* 3 | :param { tag: 'Genghis_Khan' } 4 | */ 5 | MATCH 6 | (tag:Tag {name: 'Genghis_Khan'})<-[:HAS_TAG]-(message:Message), 7 | (message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_TAG]->(relatedTag:Tag) 8 | WHERE NOT (comment)-[:HAS_TAG]->(tag) 9 | RETURN 10 | relatedTag.name, 11 | count(DISTINCT comment) AS count 12 | ORDER BY 13 | count DESC, 14 | relatedTag.name ASC 15 | LIMIT 100; 16 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi-9.cypher: -------------------------------------------------------------------------------- 1 | // Q9. Forum with related Tags 2 | /* 3 | :param { 4 | tagClass1: 'BaseballPlayer', 5 | tagClass2: 'ChristianBishop', 6 | threshold: 200 7 | } 8 | */ 9 | MATCH 10 | (forum:Forum)-[:HAS_MEMBER]->(person:Person) 11 | WITH forum, count(person) AS members 12 | WHERE members > 200 13 | MATCH 14 | (forum)-[:CONTAINER_OF]->(post1:Post)-[:HAS_TAG]-> 15 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: 'BaseballPlayer'}) 16 | WITH forum, count(DISTINCT post1) AS count1 17 | MATCH 18 | (forum)-[:CONTAINER_OF]->(post2:Post)-[:HAS_TAG]-> 19 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: 'ChristianBishop'}) 20 | WITH forum, count1, count(DISTINCT post2) AS count2 21 | RETURN 22 | forum.id, 23 | count1, 24 | count2 25 | ORDER BY 26 | abs(count2-count1) DESC, 27 | forum.id ASC 28 | LIMIT 100; 29 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/bi.sh: -------------------------------------------------------------------------------- 1 | length=$2 2 | db=$1 3 | total=0 4 | pathResult="./result" 5 | pathNeo4j="/home/zhiyi/ecosys/neo4j-community-3.5.0" 6 | for i in $( seq 1 19) 7 | do 8 | total=0 9 | for j in $( seq 1 $length ) 10 | do 11 | t0=$(date +%s%N) 12 | $pathNeo4j/bin/cypher-shell < ./bi-$i.cypher > $pathResult/bi-$i.out 13 | tn=$(date +%s%N) 14 | t=$((($tn - $t0)/1000000)) 15 | total=$(($t + $total)) 16 | echo "$db bi-$i.cypher NO.$j time: " $t >> $pathResult/time-bi.out 17 | echo "$db bi-$i.cypher NO.$j time: " $t $pathResult/time-bi.out 18 | done 19 | avg=$((total / length)) 20 | echo "$db bi-$i.cypher avg time: " $avg >> $pathResult/time-bi.out 21 | echo "$db bi-$i.cypher avg time: " $avg $pathResult/time-bi.out 22 | 23 | done 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/i-complex.sh: -------------------------------------------------------------------------------- 1 | length=$2 2 | db=$1 3 | total=0 4 | pathResult="./result" 5 | pathNeo4j="/home/zhiyi/ecosys/neo4j-community-3.5.0" 6 | for i in $( seq 13 14) 7 | do 8 | total=0 9 | for j in $( seq 1 $length ) 10 | do 11 | t0=$(date +%s%N) 12 | $pathNeo4j/bin/cypher-shell < ./interactive-complex-$i.cypher > $pathResult/interactive-complex-$i.out 13 | tn=$(date +%s%N) 14 | t=$((($tn - $t0)/1000000)) 15 | total=$(($t + $total)) 16 | echo "$db interactive-complex-$i.cypher NO.$j time: " $t >> $pathResult/time-interactive-complex.out 17 | echo "$db interactive-complex-$i.cypher NO.$j time: " $t $pathResult/time-interactive-complex.out 18 | done 19 | avg=$((total / length)) 20 | echo "$db interactive-complex-$i.cypher avg time: " $avg >> $pathResult/time-interactive-complex.out 21 | echo "$db interactive-complex-$i.cypher avg time: " $avg $pathResult/time-interactive-complex.out 22 | 23 | done 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/i-short.sh: -------------------------------------------------------------------------------- 1 | length=$2 2 | db=$1 3 | total=0 4 | pathResult="./result" 5 | pathNeo4j="/home/zhiyi/ecosys/neo4j-community-3.5.0" 6 | for i in $( seq 1 7) 7 | do 8 | total=0 9 | for j in $( seq 1 $length ) 10 | do 11 | t0=$(date +%s%N) 12 | $pathNeo4j/bin/cypher-shell < ./interactive-short-$i.cypher > $pathResult/interactive-short-$i.out 13 | tn=$(date +%s%N) 14 | t=$((($tn - $t0)/1000000)) 15 | total=$(($t + $total)) 16 | echo "$db interactive-short-$i.cypher NO.$j time: " $t >> $pathResult/time-interactive-short.out 17 | echo "$db interactive-short-$i.cypher NO.$j time: " $t $pathResult/time-interactive-short.out 18 | done 19 | avg=$((total / length)) 20 | echo "$db interactive-short-$i.cypher avg time: " $avg >> $pathResult/time-interactive-short.out 21 | echo "$db interactive-short-$i.cypher avg time: " $avg $pathResult/time-interactive-short.out 22 | 23 | done 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:933})-[path:KNOWS*1..3]-(friend:Person) 2 | WHERE friend.firstName = "Carmen" 3 | WITH friend, min(length(path)) AS distance 4 | ORDER BY distance ASC, friend.lastName ASC, toInteger(friend.id) ASC 5 | LIMIT 20 6 | MATCH (friend)-[:IS_LOCATED_IN]->(friendCity:Place) 7 | OPTIONAL MATCH (friend)-[studyAt:STUDY_AT]->(uni:Organisation)-[:IS_LOCATED_IN]->(uniCity:Place) 8 | WITH 9 | friend, 10 | collect( 11 | CASE uni.name 12 | WHEN null THEN null 13 | ELSE [uni.name, studyAt.classYear, uniCity.name] 14 | END 15 | ) AS unis, 16 | friendCity, 17 | distance 18 | OPTIONAL MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(companyCountry:Place) 19 | WITH 20 | friend, 21 | collect( 22 | CASE company.name 23 | WHEN null THEN null 24 | ELSE [company.name, workAt.workFrom, companyCountry.name] 25 | END 26 | ) AS companies, 27 | unis, 28 | friendCity, 29 | distance 30 | RETURN 31 | friend.id AS friendId, 32 | friend.lastName AS friendLastName, 33 | distance AS distanceFromPerson, 34 | friend.birthday AS friendBirthday, 35 | friend.creationDate AS friendCreationDate, 36 | friend.gender AS friendGender, 37 | friend.browserUsed AS friendBrowserUsed, 38 | friend.locationIP AS friendLocationIp, 39 | friend.email AS friendEmails, 40 | friend.speaks AS friendLanguages, 41 | friendCity.name AS friendCityName, 42 | unis AS friendUniversities, 43 | companies AS friendCompanies 44 | ORDER BY distanceFromPerson ASC, friendLastName ASC, toInteger(friendId) ASC 45 | LIMIT 20; 46 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-10-without-list-comprehension.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post)+[null] AS posts, count(post) AS postCount, person 10 | UNWIND posts AS commonPostCandidate 11 | WITH 12 | friend, 13 | city, 14 | commonPostCandidate, 15 | postCount, 16 | person 17 | WHERE (commonPostCandidate)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person) OR commonPostCandidate IS NULL 18 | WITH 19 | friend, 20 | city, 21 | postCount, 22 | count(commonPostCandidate) AS commonPostCount 23 | RETURN 24 | friend.id AS personId, 25 | friend.firstName AS personFirstName, 26 | friend.lastName AS personLastName, 27 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 28 | commonPostCount, 29 | postCount, 30 | friend.gender AS personGender, 31 | city.name AS personCityName 32 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 33 | LIMIT 10 34 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-10.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post) AS posts, person 10 | WITH 11 | friend, 12 | city, 13 | length(posts) AS postCount, 14 | length([p IN posts WHERE (p)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person)]) AS commonPostCount 15 | RETURN 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 20 | friend.gender AS personGender, 21 | city.name AS personCityName 22 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 23 | LIMIT 10 24 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-11.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person) 2 | WHERE not(person=friend) 3 | WITH DISTINCT friend 4 | MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(:Place {name:$countryName}) 5 | WHERE workAt.workFrom < $workFromYear 6 | RETURN 7 | friend.id AS personId, 8 | friend.firstName AS personFirstName, 9 | friend.lastName AS personLastName, 10 | company.name AS organizationName, 11 | workAt.workFrom AS organizationWorkFromYear 12 | ORDER BY organizationWorkFromYear ASC, toInteger(personId) ASC, organizationName DESC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-12.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF]->(:Post)-[:HAS_TAG]->(tag:Tag), 2 | (tag)-[:HAS_TYPE]->(tagClass:TagClass)-[:IS_SUBCLASS_OF*0..]->(baseTagClass:TagClass) 3 | WHERE tagClass.name = $tagClassName OR baseTagClass.name = $tagClassName 4 | RETURN 5 | friend.id AS personId, 6 | friend.firstName AS personFirstName, 7 | friend.lastName AS personLastName, 8 | collect(DISTINCT tag.name) AS tagNames, 9 | count(DISTINCT comment) AS replyCount 10 | ORDER BY replyCount DESC, toInteger(personId) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-13.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person1:Person {id:933}), (person2:Person {id:1129}) 2 | OPTIONAL MATCH path = shortestPath((person1)-[:KNOWS*]-(person2)) 3 | RETURN 4 | CASE path IS NULL 5 | WHEN true THEN -1 6 | ELSE length(path) 7 | END AS shortestPathLength; 8 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-14.cypher: -------------------------------------------------------------------------------- 1 | MATCH path = allShortestPaths((person1:Person {id:$person1Id})-[:KNOWS*..15]-(person2:Person {id:$person2Id})) 2 | WITH nodes(path) AS pathNodes 3 | RETURN 4 | extract(n IN pathNodes | n.id) AS personIdsInPath, 5 | reduce(weight=0.0, idx IN range(1,size(pathNodes)-1) | extract(prev IN [pathNodes[idx-1]] | extract(curr IN [pathNodes[idx]] | weight + length((curr)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(prev))*1.0 + length((prev)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(curr))*1.0 + length((prev)-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]-(:Comment)-[:HAS_CREATOR]-(curr))*0.5) )[0][0]) AS pathWight 6 | ORDER BY pathWight DESC 7 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:933})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate <= 20110817060540595 3 | RETURN 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS postOrCommentId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS postOrCommentContent, 12 | message.creationDate AS postOrCommentCreationDate 13 | ORDER BY postOrCommentCreationDate DESC, toInteger(postOrCommentId) ASC 14 | LIMIT 20; 15 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(messageX:Message), 2 | (messageX)-[:IS_LOCATED_IN]->(countryX:Place) 3 | WHERE 4 | not(person=friend) 5 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryX)) 6 | AND countryX.name=$countryXName AND messageX.creationDate>=$startDate 7 | AND messageX.creationDate<$endDate 8 | WITH friend, count(DISTINCT messageX) AS xCount 9 | MATCH (friend)<-[:HAS_CREATOR]-(messageY:Message)-[:IS_LOCATED_IN]->(countryY:Place) 10 | WHERE 11 | countryY.name=$countryYName 12 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryY)) 13 | AND messageY.creationDate>=$startDate 14 | AND messageY.creationDate<$endDate 15 | WITH 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | xCount, 20 | count(DISTINCT messageY) AS yCount 21 | RETURN 22 | personId, 23 | personFirstName, 24 | personLastName, 25 | xCount, 26 | yCount, 27 | xCount + yCount AS count 28 | ORDER BY count DESC, toInteger(personId) ASC 29 | LIMIT 20; 30 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS]-(:Person)<-[:HAS_CREATOR]-(post:Post)-[:HAS_TAG]->(tag:Tag) 2 | WHERE post.creationDate >= $startDate 3 | AND post.creationDate < $endDate 4 | WITH person, count(post) AS postsOnTag, tag 5 | OPTIONAL MATCH (person)-[:KNOWS]-()<-[:HAS_CREATOR]-(oldPost:Post)-[:HAS_TAG]->(tag) 6 | WHERE oldPost.creationDate < $startDate 7 | WITH person, postsOnTag, tag, count(oldPost) AS cp 8 | WHERE cp = 0 9 | RETURN 10 | tag.name AS tagName, 11 | sum(postsOnTag) AS postCount 12 | ORDER BY postCount DESC, tagName ASC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[membership:HAS_MEMBER]-(forum:Forum) 2 | WHERE membership.joinDate>$minDate 3 | AND not(person=friend) 4 | WITH DISTINCT friend, forum 5 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(forum) 6 | WITH forum, count(post) AS postCount 7 | RETURN 8 | forum.title AS forumTitle, 9 | postCount 10 | ORDER BY postCount DESC, toInteger(forum.id) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (person:Person {id:933})-[:KNOWS*1..2]-(friend:Person), 3 | (friend)<-[:HAS_CREATOR]-(friendPost:Post)-[:HAS_TAG]->(knownTag:Tag {name:Hamid_Karzai}) 4 | WHERE not(person=friend) 5 | MATCH (friendPost)-[:HAS_TAG]->(commonTag:Tag) 6 | WHERE not(commonTag=knownTag) 7 | WITH DISTINCT commonTag, knownTag, friend 8 | MATCH (commonTag)<-[:HAS_TAG]-(commonPost:Post)-[:HAS_TAG]->(knownTag) 9 | WHERE (commonPost)-[:HAS_CREATOR]->(friend) 10 | RETURN 11 | commonTag.name AS tagName, 12 | count(commonPost) AS postCount 13 | ORDER BY postCount DESC, tagName ASC 14 | LIMIT 10; 15 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-7-with-lists.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})<-[:HAS_CREATOR]-(message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | collect([message, likeTime]) AS latestLikes, 7 | person 8 | WITH 9 | liker, 10 | head(latestLikes) AS latestLike, 11 | person 12 | RETURN 13 | liker.id AS personId, 14 | liker.firstName AS personFirstName, 15 | liker.lastName AS personLastName, 16 | latestLike[1] AS likeCreationDate, 17 | latestLike[0].id AS commentOrPostId, 18 | CASE exists(latestLike[0].content) 19 | WHEN true THEN latestLike[0].content 20 | ELSE latestLike[0].imageFile 21 | END AS commentOrPostContent, 22 | latestLike[0].creationDate AS commentOrPostCreationDate, 23 | not((liker)-[:KNOWS]-(person)) AS isNew 24 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 25 | LIMIT 20 26 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$933})<-[:HAS_CREATOR]-(message:Message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | head(collect({msg: message, likeTime: likeTime})) AS latestLike, 7 | person 8 | RETURN 9 | liker.id AS personId, 10 | liker.firstName AS personFirstName, 11 | liker.lastName AS personLastName, 12 | latestLike.likeTime AS likeCreationDate, 13 | latestLike.msg.id AS commentOrPostId, 14 | CASE exists(latestLike.msg.content) 15 | WHEN true THEN latestLike.msg.content 16 | ELSE latestLike.msg.imageFile 17 | END AS commentOrPostContent, 18 | latestLike.msg.creationDate AS commentOrPostCreationDate, 19 | not((liker)-[:KNOWS]-(person)) AS isNew 20 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 21 | LIMIT 20; 22 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (start:Person {id:933})<-[:HAS_CREATOR]-(:Message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_CREATOR]->(person:Person) 3 | RETURN 4 | person.id AS personId, 5 | person.firstName AS personFirstName, 6 | person.lastName AS personLastName, 7 | comment.creationDate AS commentCreationDate, 8 | comment.id AS commentId, 9 | comment.content AS commentContent 10 | ORDER BY commentCreationDate DESC, toInteger(commentId) ASC 11 | LIMIT 20; 12 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-complex-9.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:933})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate < $maxDate 3 | RETURN DISTINCT 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS commentOrPostId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS commentOrPostContent, 12 | message.creationDate AS commentOrPostCreationDate 13 | ORDER BY message.creationDate DESC, toInteger(message.id) ASC 14 | LIMIT 20; 15 | 16 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:933})-[:IS_LOCATED_IN]->(p:Place) 2 | RETURN 3 | n.firstName AS firstName, 4 | n.lastName AS lastName, 5 | n.birthday AS birthday, 6 | n.locationIP AS locationIP, 7 | n.browserUsed AS browserUsed, 8 | p.id AS cityId, 9 | n.gender AS gender, 10 | n.creationDate AS creationDate; 11 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:933})<-[:HAS_CREATOR]-(m:Message)-[:REPLY_OF*0..]->(p:Post) 2 | MATCH (p)-[:HAS_CREATOR]->(c) 3 | RETURN 4 | m.id as messageId, 5 | CASE exists(m.content) 6 | WHEN true THEN m.content 7 | ELSE m.imageFile 8 | END AS messageContent, 9 | m.creationDate AS messageCreationDate, 10 | p.id AS originalPostId, 11 | c.id AS originalPostAuthorId, 12 | c.firstName as originalPostAuthorFirstName, 13 | c.lastName as originalPostAuthorLastName 14 | ORDER BY messageCreationDate DESC 15 | LIMIT 10; 16 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:933})-[r:KNOWS]-(friend) 2 | RETURN 3 | friend.id AS personId, 4 | friend.firstName AS firstName, 5 | friend.lastName AS lastName, 6 | r.creationDate AS friendshipCreationDate 7 | ORDER BY friendshipCreationDate DESC, toInteger(personId) ASC; 8 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:1236950581248}) 2 | RETURN 3 | m.creationDate as messageCreationDate, 4 | CASE exists(m.content) 5 | WHEN true THEN m.content 6 | ELSE m.imageFile 7 | END AS messageContent; 8 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:1236950581248})-[:HAS_CREATOR]->(p:Person) 2 | RETURN 3 | p.id AS personId, 4 | p.firstName AS firstName, 5 | p.lastName AS lastName; 6 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:1236950581248})-[:REPLY_OF*0..]->(p:Post)<-[:CONTAINER_OF]-(f:Forum)-[:HAS_MODERATOR]->(mod:Person) 2 | RETURN 3 | f.id AS forumId, 4 | f.title AS forumTitle, 5 | mod.id AS moderatorId, 6 | mod.firstName AS moderatorFirstName, 7 | mod.lastName AS moderatorLastName; 8 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-short-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:1236950581248})<-[:REPLY_OF]-(c:Comment)-[:HAS_CREATOR]->(p:Person) 2 | OPTIONAL MATCH (m)-[:HAS_CREATOR]->(a:Person)-[r:KNOWS]-(p) 3 | RETURN 4 | c.id AS commentId, 5 | c.content AS commentContent, 6 | c.creationDate AS commentCreationDate, 7 | p.id AS replyAuthorId, 8 | p.firstName AS replyAuthorFirstName, 9 | p.lastName AS replyAuthorLastName, 10 | CASE r 11 | WHEN null THEN false 12 | ELSE true 13 | END AS replyAuthorKnowsOriginalMessageAuthor 14 | ORDER BY commentCreationDate DESC, replyAuthorId; 15 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (c:City {id:$cityId}) 2 | CREATE (p:Person {id: $personId, firstName: $personFirstName, lastName: $personLastName, gender: $gender, birthday: $birthday, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, speaks: $languages, emails: $emails})-[:IS_LOCATED_IN]->(c) 3 | WITH p, count(*) AS dummy1 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_INTEREST]->(t) 7 | WITH p, count(*) AS dummy2 8 | UNWIND $studyAt AS s 9 | MATCH (u:Organisation {id: s[0]}) 10 | CREATE (p)-[:STUDY_AT {classYear: s[1]}]->(u) 11 | WITH p, count(*) AS dummy3 12 | UNWIND $workAt AS w 13 | MATCH (comp:Organisation {id: w[0]}) 14 | CREATE (p)-[:WORKS_AT {workFrom: w[1]}]->(comp) 15 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(post:Post {id:$postId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(post) 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(comment:Comment {id:$commentId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(comment) 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p:Person {id: $moderatorPersonId}) 2 | CREATE (f:Forum {id: $forumId, title: $forumTitle, creationDate: $creationDate})-[:HAS_MODERATOR]->(p) 3 | WITH f 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (f)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (f:Forum {id:$forumId}), (p:Person {id:$personId}) 2 | CREATE (f)-[:HAS_MEMBER {joinDate:$joinDate}]->(p) 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (author:Person {id: $authorPersonId}), (country:Country {id: $countryId}), (forum:Forum {id: $forumId}) 2 | CREATE (author)<-[:HAS_CREATOR]-(p:Post:Message {id: $postId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: CASE $content WHEN '' THEN null ELSE $content END, imageFile: CASE $imageFile WHEN '' THEN null ELSE $imageFile END, length: $length})<-[:CONTAINER_OF]-(forum), (p)-[:IS_LOCATED_IN]->(country) 3 | WITH p 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (author:Person {id: $authorPersonId}), 3 | (country:Country {id: $countryId}), 4 | (message:Message {id: CASE $replyToPostId WHEN -1 THEN $replyToCommentId ELSE $replyToPostId END}) 5 | CREATE (author)<-[:HAS_CREATOR]-(c:Comment:Message {id: $commentId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: $content, length: $length})-[:REPLY_OF]->(message), (c)-[:IS_LOCATED_IN]->(country) 6 | WITH c 7 | UNWIND $tagIds AS tagId 8 | MATCH (t:Tag {id: tagId}) 9 | CREATE (c)-[:HAS_TAG]->(t) 10 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/interactive-update-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p1:Person {id:$person1Id}), (p2:Person {id:$person2Id}) 2 | CREATE (p1)-[:KNOWS {creationDate:$creationDate}]->(p2) 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-1.out: -------------------------------------------------------------------------------- 1 | firstName, lastName, birthday, locationIP, browserUsed, cityId, gender, creationDate 2 | "Mahinda", "Perera", 19891203, "119.235.7.103", "Firefox", 1353, "male", 20100214153210447 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-2.out: -------------------------------------------------------------------------------- 1 | messageId, messageContent, messageCreationDate, originalPostId, originalPostAuthorId, originalPostAuthorFirstName, originalPostAuthorLastName 2 | 2199027727462, "good", 20120909020743979, 2061588773973, 32985348833579, "Otto", "Becker" 3 | 2199023255745, "photo2199023255745.jpg", 20120908162059879, 2199023255745, 933, "Mahinda", "Perera" 4 | 2199023255744, "photo2199023255744.jpg", 20120908162058879, 2199023255744, 933, "Mahinda", "Perera" 5 | 2199023255743, "photo2199023255743.jpg", 20120908162057879, 2199023255743, 933, "Mahinda", "Perera" 6 | 2199023255742, "photo2199023255742.jpg", 20120908162056879, 2199023255742, 933, "Mahinda", "Perera" 7 | 2199023255741, "photo2199023255741.jpg", 20120908162055879, 2199023255741, 933, "Mahinda", "Perera" 8 | 2199023255740, "photo2199023255740.jpg", 20120908162054879, 2199023255740, 933, "Mahinda", "Perera" 9 | 2199023255739, "photo2199023255739.jpg", 20120908162053879, 2199023255739, 933, "Mahinda", "Perera" 10 | 2199023255738, "photo2199023255738.jpg", 20120908162052879, 2199023255738, 933, "Mahinda", "Perera" 11 | 2199023255737, "photo2199023255737.jpg", 20120908162051879, 2199023255737, 933, "Mahinda", "Perera" 12 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-3.out: -------------------------------------------------------------------------------- 1 | personId, firstName, lastName, friendshipCreationDate 2 | 32985348833579, "Otto", "Becker", 20120907011130195 3 | 32985348838375, "Otto", "Richter", 20120717080449463 4 | 10995116284808, "Andrei", "Condariuc", 20110102064341955 5 | 6597069777240, "Fritz", "Muller", 20100920094243187 6 | 4139, "Baruch", "Dego", 20100313073721718 7 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-4.out: -------------------------------------------------------------------------------- 1 | messageCreationDate, messageContent 2 | 20110817060540595, "About Rupert Murdoch, t newer electronic publishing technoAbout George Frideric Handel, concertos. Handel was born in 1685,About Kurt Vonne" 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-5.out: -------------------------------------------------------------------------------- 1 | personId, firstName, lastName 2 | 933, "Mahinda", "Perera" 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-6.out: -------------------------------------------------------------------------------- 1 | forumId, forumTitle, moderatorId, moderatorFirstName, moderatorLastName 2 | 0, "Wall of Mahinda Perera", 933, "Mahinda", "Perera" 3 | -------------------------------------------------------------------------------- /neo4j/queries/fix-query/result/interactive-short-7.out: -------------------------------------------------------------------------------- 1 | commentId, commentContent, commentCreationDate, replyAuthorId, replyAuthorFirstName, replyAuthorLastName, replyAuthorKnowsOriginalMessageAuthor 2 | 1236950581249, "yes", 20110817142659961, 10995116284808, "Andrei", "Condariuc", TRUE 3 | 1236950581250, "thanks", 20110817111021570, 4139, "Baruch", "Dego", TRUE 4 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[path:KNOWS*1..3]-(friend:Person) 2 | WHERE friend.firstName = $firstName 3 | WITH friend, min(length(path)) AS distance 4 | ORDER BY distance ASC, friend.lastName ASC, toInteger(friend.id) ASC 5 | LIMIT 20 6 | MATCH (friend)-[:IS_LOCATED_IN]->(friendCity:Place) 7 | OPTIONAL MATCH (friend)-[studyAt:STUDY_AT]->(uni:Organisation)-[:IS_LOCATED_IN]->(uniCity:Place) 8 | WITH 9 | friend, 10 | collect( 11 | CASE uni.name 12 | WHEN null THEN null 13 | ELSE [uni.name, studyAt.classYear, uniCity.name] 14 | END 15 | ) AS unis, 16 | friendCity, 17 | distance 18 | OPTIONAL MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(companyCountry:Place) 19 | WITH 20 | friend, 21 | collect( 22 | CASE company.name 23 | WHEN null THEN null 24 | ELSE [company.name, workAt.workFrom, companyCountry.name] 25 | END 26 | ) AS companies, 27 | unis, 28 | friendCity, 29 | distance 30 | RETURN 31 | friend.id AS friendId, 32 | friend.lastName AS friendLastName, 33 | distance AS distanceFromPerson, 34 | friend.birthday AS friendBirthday, 35 | friend.creationDate AS friendCreationDate, 36 | friend.gender AS friendGender, 37 | friend.browserUsed AS friendBrowserUsed, 38 | friend.locationIP AS friendLocationIp, 39 | friend.email AS friendEmails, 40 | friend.speaks AS friendLanguages, 41 | friendCity.name AS friendCityName, 42 | unis AS friendUniversities, 43 | companies AS friendCompanies 44 | ORDER BY distanceFromPerson ASC, friendLastName ASC, toInteger(friendId) ASC 45 | LIMIT 20 46 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-10-without-list-comprehension.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post)+[null] AS posts, count(post) AS postCount, person 10 | UNWIND posts AS commonPostCandidate 11 | WITH 12 | friend, 13 | city, 14 | commonPostCandidate, 15 | postCount, 16 | person 17 | WHERE (commonPostCandidate)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person) OR commonPostCandidate IS NULL 18 | WITH 19 | friend, 20 | city, 21 | postCount, 22 | count(commonPostCandidate) AS commonPostCount 23 | RETURN 24 | friend.id AS personId, 25 | friend.firstName AS personFirstName, 26 | friend.lastName AS personLastName, 27 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 28 | commonPostCount, 29 | postCount, 30 | friend.gender AS personGender, 31 | city.name AS personCityName 32 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 33 | LIMIT 10 34 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-10.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post) AS posts, person 10 | WITH 11 | friend, 12 | city, 13 | length(posts) AS postCount, 14 | length([p IN posts WHERE (p)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person)]) AS commonPostCount 15 | RETURN 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 20 | friend.gender AS personGender, 21 | city.name AS personCityName 22 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 23 | LIMIT 10 24 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-11.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person) 2 | WHERE not(person=friend) 3 | WITH DISTINCT friend 4 | MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(:Place {name:$countryName}) 5 | WHERE workAt.workFrom < $workFromYear 6 | RETURN 7 | friend.id AS personId, 8 | friend.firstName AS personFirstName, 9 | friend.lastName AS personLastName, 10 | company.name AS organizationName, 11 | workAt.workFrom AS organizationWorkFromYear 12 | ORDER BY organizationWorkFromYear ASC, toInteger(personId) ASC, organizationName DESC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-12.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF]->(:Post)-[:HAS_TAG]->(tag:Tag), 2 | (tag)-[:HAS_TYPE]->(tagClass:TagClass)-[:IS_SUBCLASS_OF*0..]->(baseTagClass:TagClass) 3 | WHERE tagClass.name = $tagClassName OR baseTagClass.name = $tagClassName 4 | RETURN 5 | friend.id AS personId, 6 | friend.firstName AS personFirstName, 7 | friend.lastName AS personLastName, 8 | collect(DISTINCT tag.name) AS tagNames, 9 | count(DISTINCT comment) AS replyCount 10 | ORDER BY replyCount DESC, toInteger(personId) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-13.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person1:Person {id:$person1Id}), (person2:Person {id:$person2Id}) 2 | OPTIONAL MATCH path = shortestPath((person1)-[:KNOWS*]-(person2)) 3 | RETURN 4 | CASE path IS NULL 5 | WHEN true THEN -1 6 | ELSE length(path) 7 | END AS shortestPathLength; 8 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-14.cypher: -------------------------------------------------------------------------------- 1 | MATCH path = allShortestPaths((person1:Person {id:$person1Id})-[:KNOWS*..15]-(person2:Person {id:$person2Id})) 2 | WITH nodes(path) AS pathNodes 3 | RETURN 4 | extract(n IN pathNodes | n.id) AS personIdsInPath, 5 | reduce(weight=0.0, idx IN range(1,size(pathNodes)-1) | extract(prev IN [pathNodes[idx-1]] | extract(curr IN [pathNodes[idx]] | weight + length((curr)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(prev))*1.0 + length((prev)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(curr))*1.0 + length((prev)-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]-(:Comment)-[:HAS_CREATOR]-(curr))*0.5) )[0][0]) AS pathWight 6 | ORDER BY pathWight DESC 7 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate <= $maxDate 3 | RETURN 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS postOrCommentId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS postOrCommentContent, 12 | message.creationDate AS postOrCommentCreationDate 13 | ORDER BY postOrCommentCreationDate DESC, toInteger(postOrCommentId) ASC 14 | LIMIT 20 15 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(messageX:Message), 2 | (messageX)-[:IS_LOCATED_IN]->(countryX:Place) 3 | WHERE 4 | not(person=friend) 5 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryX)) 6 | AND countryX.name=$countryXName AND messageX.creationDate>=$startDate 7 | AND messageX.creationDate<$endDate 8 | WITH friend, count(DISTINCT messageX) AS xCount 9 | MATCH (friend)<-[:HAS_CREATOR]-(messageY:Message)-[:IS_LOCATED_IN]->(countryY:Place) 10 | WHERE 11 | countryY.name=$countryYName 12 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryY)) 13 | AND messageY.creationDate>=$startDate 14 | AND messageY.creationDate<$endDate 15 | WITH 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | xCount, 20 | count(DISTINCT messageY) AS yCount 21 | RETURN 22 | personId, 23 | personFirstName, 24 | personLastName, 25 | xCount, 26 | yCount, 27 | xCount + yCount AS count 28 | ORDER BY count DESC, toInteger(personId) ASC 29 | LIMIT 20 30 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS]-(:Person)<-[:HAS_CREATOR]-(post:Post)-[:HAS_TAG]->(tag:Tag) 2 | WHERE post.creationDate >= $startDate 3 | AND post.creationDate < $endDate 4 | WITH person, count(post) AS postsOnTag, tag 5 | OPTIONAL MATCH (person)-[:KNOWS]-()<-[:HAS_CREATOR]-(oldPost:Post)-[:HAS_TAG]->(tag) 6 | WHERE oldPost.creationDate < $startDate 7 | WITH person, postsOnTag, tag, count(oldPost) AS cp 8 | WHERE cp = 0 9 | RETURN 10 | tag.name AS tagName, 11 | sum(postsOnTag) AS postCount 12 | ORDER BY postCount DESC, tagName ASC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[membership:HAS_MEMBER]-(forum:Forum) 2 | WHERE membership.joinDate>$minDate 3 | AND not(person=friend) 4 | WITH DISTINCT friend, forum 5 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(forum) 6 | WITH forum, count(post) AS postCount 7 | RETURN 8 | forum.title AS forumTitle, 9 | postCount 10 | ORDER BY postCount DESC, toInteger(forum.id) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person), 3 | (friend)<-[:HAS_CREATOR]-(friendPost:Post)-[:HAS_TAG]->(knownTag:Tag {name:$tagName}) 4 | WHERE not(person=friend) 5 | MATCH (friendPost)-[:HAS_TAG]->(commonTag:Tag) 6 | WHERE not(commonTag=knownTag) 7 | WITH DISTINCT commonTag, knownTag, friend 8 | MATCH (commonTag)<-[:HAS_TAG]-(commonPost:Post)-[:HAS_TAG]->(knownTag) 9 | WHERE (commonPost)-[:HAS_CREATOR]->(friend) 10 | RETURN 11 | commonTag.name AS tagName, 12 | count(commonPost) AS postCount 13 | ORDER BY postCount DESC, tagName ASC 14 | LIMIT 10 15 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-7-with-lists.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})<-[:HAS_CREATOR]-(message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | collect([message, likeTime]) AS latestLikes, 7 | person 8 | WITH 9 | liker, 10 | head(latestLikes) AS latestLike, 11 | person 12 | RETURN 13 | liker.id AS personId, 14 | liker.firstName AS personFirstName, 15 | liker.lastName AS personLastName, 16 | latestLike[1] AS likeCreationDate, 17 | latestLike[0].id AS commentOrPostId, 18 | CASE exists(latestLike[0].content) 19 | WHEN true THEN latestLike[0].content 20 | ELSE latestLike[0].imageFile 21 | END AS commentOrPostContent, 22 | latestLike[0].creationDate AS commentOrPostCreationDate, 23 | not((liker)-[:KNOWS]-(person)) AS isNew 24 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 25 | LIMIT 20 26 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})<-[:HAS_CREATOR]-(message:Message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | head(collect({msg: message, likeTime: likeTime})) AS latestLike, 7 | person 8 | RETURN 9 | liker.id AS personId, 10 | liker.firstName AS personFirstName, 11 | liker.lastName AS personLastName, 12 | latestLike.likeTime AS likeCreationDate, 13 | latestLike.msg.id AS commentOrPostId, 14 | CASE exists(latestLike.msg.content) 15 | WHEN true THEN latestLike.msg.content 16 | ELSE latestLike.msg.imageFile 17 | END AS commentOrPostContent, 18 | latestLike.msg.creationDate AS commentOrPostCreationDate, 19 | not((liker)-[:KNOWS]-(person)) AS isNew 20 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 21 | LIMIT 20 22 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (start:Person {id:$personId})<-[:HAS_CREATOR]-(:Message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_CREATOR]->(person:Person) 3 | RETURN 4 | person.id AS personId, 5 | person.firstName AS personFirstName, 6 | person.lastName AS personLastName, 7 | comment.creationDate AS commentCreationDate, 8 | comment.id AS commentId, 9 | comment.content AS commentContent 10 | ORDER BY commentCreationDate DESC, toInteger(commentId) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-complex-9.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate < $maxDate 3 | RETURN DISTINCT 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS commentOrPostId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS commentOrPostContent, 12 | message.creationDate AS commentOrPostCreationDate 13 | ORDER BY message.creationDate DESC, toInteger(message.id) ASC 14 | LIMIT 20 15 | 16 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:$personId})-[:IS_LOCATED_IN]->(p:Place) 2 | RETURN 3 | n.firstName AS firstName, 4 | n.lastName AS lastName, 5 | n.birthday AS birthday, 6 | n.locationIP AS locationIP, 7 | n.browserUsed AS browserUsed, 8 | p.id AS cityId, 9 | n.gender AS gender, 10 | n.creationDate AS creationDate 11 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})<-[:HAS_CREATOR]-(m:Message)-[:REPLY_OF*0..]->(p:Post) 2 | MATCH (p)-[:HAS_CREATOR]->(c) 3 | RETURN 4 | m.id as messageId, 5 | CASE exists(m.content) 6 | WHEN true THEN m.content 7 | ELSE m.imageFile 8 | END AS messageContent, 9 | m.creationDate AS messageCreationDate, 10 | p.id AS originalPostId, 11 | c.id AS originalPostAuthorId, 12 | c.firstName as originalPostAuthorFirstName, 13 | c.lastName as originalPostAuthorLastName 14 | ORDER BY messageCreationDate DESC 15 | LIMIT 10 16 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:$personId})-[r:KNOWS]-(friend) 2 | RETURN 3 | friend.id AS personId, 4 | friend.firstName AS firstName, 5 | friend.lastName AS lastName, 6 | r.creationDate AS friendshipCreationDate 7 | ORDER BY friendshipCreationDate DESC, toInteger(personId) ASC 8 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId}) 2 | RETURN 3 | m.creationDate as messageCreationDate, 4 | CASE exists(m.content) 5 | WHEN true THEN m.content 6 | ELSE m.imageFile 7 | END AS messageContent 8 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})-[:HAS_CREATOR]->(p:Person) 2 | RETURN 3 | p.id AS personId, 4 | p.firstName AS firstName, 5 | p.lastName AS lastName 6 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})-[:REPLY_OF*0..]->(p:Post)<-[:CONTAINER_OF]-(f:Forum)-[:HAS_MODERATOR]->(mod:Person) 2 | RETURN 3 | f.id AS forumId, 4 | f.title AS forumTitle, 5 | mod.id AS moderatorId, 6 | mod.firstName AS moderatorFirstName, 7 | mod.lastName AS moderatorLastName 8 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-short-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})<-[:REPLY_OF]-(c:Comment)-[:HAS_CREATOR]->(p:Person) 2 | OPTIONAL MATCH (m)-[:HAS_CREATOR]->(a:Person)-[r:KNOWS]-(p) 3 | RETURN 4 | c.id AS commentId, 5 | c.content AS commentContent, 6 | c.creationDate AS commentCreationDate, 7 | p.id AS replyAuthorId, 8 | p.firstName AS replyAuthorFirstName, 9 | p.lastName AS replyAuthorLastName, 10 | CASE r 11 | WHEN null THEN false 12 | ELSE true 13 | END AS replyAuthorKnowsOriginalMessageAuthor 14 | ORDER BY commentCreationDate DESC, replyAuthorId 15 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (c:City {id:$cityId}) 2 | CREATE (p:Person {id: $personId, firstName: $personFirstName, lastName: $personLastName, gender: $gender, birthday: $birthday, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, speaks: $languages, emails: $emails})-[:IS_LOCATED_IN]->(c) 3 | WITH p, count(*) AS dummy1 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_INTEREST]->(t) 7 | WITH p, count(*) AS dummy2 8 | UNWIND $studyAt AS s 9 | MATCH (u:Organisation {id: s[0]}) 10 | CREATE (p)-[:STUDY_AT {classYear: s[1]}]->(u) 11 | WITH p, count(*) AS dummy3 12 | UNWIND $workAt AS w 13 | MATCH (comp:Organisation {id: w[0]}) 14 | CREATE (p)-[:WORKS_AT {workFrom: w[1]}]->(comp) 15 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(post:Post {id:$postId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(post) 3 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(comment:Comment {id:$commentId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(comment) 3 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p:Person {id: $moderatorPersonId}) 2 | CREATE (f:Forum {id: $forumId, title: $forumTitle, creationDate: $creationDate})-[:HAS_MODERATOR]->(p) 3 | WITH f 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (f)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (f:Forum {id:$forumId}), (p:Person {id:$personId}) 2 | CREATE (f)-[:HAS_MEMBER {joinDate:$joinDate}]->(p) 3 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (author:Person {id: $authorPersonId}), (country:Country {id: $countryId}), (forum:Forum {id: $forumId}) 2 | CREATE (author)<-[:HAS_CREATOR]-(p:Post:Message {id: $postId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: CASE $content WHEN '' THEN null ELSE $content END, imageFile: CASE $imageFile WHEN '' THEN null ELSE $imageFile END, length: $length})<-[:CONTAINER_OF]-(forum), (p)-[:IS_LOCATED_IN]->(country) 3 | WITH p 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (author:Person {id: $authorPersonId}), 3 | (country:Country {id: $countryId}), 4 | (message:Message {id: CASE $replyToPostId WHEN -1 THEN $replyToCommentId ELSE $replyToPostId END}) 5 | CREATE (author)<-[:HAS_CREATOR]-(c:Comment:Message {id: $commentId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: $content, length: $length})-[:REPLY_OF]->(message), (c)-[:IS_LOCATED_IN]->(country) 6 | WITH c 7 | UNWIND $tagIds AS tagId 8 | MATCH (t:Tag {id: tagId}) 9 | CREATE (c)-[:HAS_TAG]->(t) 10 | -------------------------------------------------------------------------------- /neo4j/queries/interactive-update-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p1:Person {id:$person1Id}), (p2:Person {id:$person2Id}) 2 | CREATE (p1)-[:KNOWS {creationDate:$creationDate}]->(p2) 3 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-1.cypher: -------------------------------------------------------------------------------- 1 | // Q1. Posting summary 2 | /* 3 | :param { date: 20110721220000000 } 4 | */ 5 | MATCH (message:Message) 6 | WHERE message.creationDate < $date 7 | WITH count(message) AS totalMessageCountInt // this should be a subquery once Cypher supports it 8 | WITH toFloat(totalMessageCountInt) AS totalMessageCount 9 | MATCH (message:Message) 10 | WHERE message.creationDate < $date 11 | AND message.content IS NOT NULL 12 | WITH 13 | totalMessageCount, 14 | message, 15 | message.creationDate/10000000000000 AS year 16 | WITH 17 | totalMessageCount, 18 | year, 19 | message:Comment AS isComment, 20 | CASE 21 | WHEN message.length < 40 THEN 0 22 | WHEN message.length < 80 THEN 1 23 | WHEN message.length < 160 THEN 2 24 | ELSE 3 25 | END AS lengthCategory, 26 | count(message) AS messageCount, 27 | floor(avg(message.length)) AS averageMessageLength, 28 | sum(message.length) AS sumMessageLength 29 | RETURN 30 | year, 31 | isComment, 32 | lengthCategory, 33 | messageCount, 34 | averageMessageLength, 35 | sumMessageLength, 36 | messageCount / totalMessageCount AS percentageOfMessages 37 | ORDER BY 38 | year DESC, 39 | isComment ASC, 40 | lengthCategory ASC 41 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-10.cypher: -------------------------------------------------------------------------------- 1 | // Q10. Central Person for a Tag 2 | /* 3 | :param { 4 | tag: 'John_Rhys-Davies', 5 | date: 20120122000000000 6 | } 7 | */ 8 | MATCH (tag:Tag {name: $tag}) 9 | // score 10 | OPTIONAL MATCH (tag)<-[interest:HAS_INTEREST]-(person:Person) 11 | WITH tag, collect(person) AS interestedPersons 12 | OPTIONAL MATCH (tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 13 | WHERE message.creationDate > $date 14 | WITH tag, interestedPersons + collect(person) AS persons 15 | UNWIND persons AS person 16 | // poor man's disjunct union (should be changed to UNION + post-union processing in the future) 17 | WITH DISTINCT tag, person 18 | WITH 19 | tag, 20 | person, 21 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(person) | interest]) 22 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person) WHERE message.creationDate > $date | message]) 23 | AS score 24 | OPTIONAL MATCH (person)-[:KNOWS]-(friend) 25 | WITH 26 | person, 27 | score, 28 | 100 * length([(tag)<-[interest:HAS_INTEREST]-(friend) | interest]) 29 | + length([(tag)<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(friend) WHERE message.creationDate > $date | message]) 30 | AS friendScore 31 | RETURN 32 | person.id, 33 | score, 34 | sum(friendScore) AS friendsScore 35 | ORDER BY 36 | score + friendsScore DESC, 37 | person.id ASC 38 | LIMIT 100 39 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-11.cypher: -------------------------------------------------------------------------------- 1 | // Q11. Unrelated replies 2 | /* 3 | :param { 4 | country: 'Germany', 5 | blacklist: ['also', 'Pope', 'that', 'James', 'Henry', 'one', 'Green'] 6 | } 7 | */ 8 | WITH $blacklist AS blacklist 9 | MATCH 10 | (country:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 11 | (person:Person)<-[:HAS_CREATOR]-(reply:Comment)-[:REPLY_OF]->(message:Message), 12 | (reply)-[:HAS_TAG]->(tag:Tag) 13 | WHERE NOT (message)-[:HAS_TAG]->(:Tag)<-[:HAS_TAG]-(reply) 14 | AND size([word IN blacklist WHERE reply.content CONTAINS word | word]) = 0 15 | OPTIONAL MATCH 16 | (:Person)-[like:LIKES]->(reply) 17 | RETURN 18 | person.id, 19 | tag.name, 20 | count(DISTINCT like) AS countLikes, 21 | count(DISTINCT reply) AS countReplies 22 | ORDER BY 23 | countLikes DESC, 24 | person.id ASC, 25 | tag.name ASC 26 | LIMIT 100 27 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-12.cypher: -------------------------------------------------------------------------------- 1 | // Q12. Trending Posts 2 | /* 3 | :param { 4 | date: 20110721220000000, 5 | likeThreshold: 400 6 | } 7 | */ 8 | MATCH 9 | (message:Message)-[:HAS_CREATOR]->(creator:Person), 10 | (message)<-[like:LIKES]-(:Person) 11 | WHERE message.creationDate > $date 12 | WITH message, creator, count(like) AS likeCount 13 | WHERE likeCount > $likeThreshold 14 | RETURN 15 | message.id, 16 | message.creationDate, 17 | creator.firstName, 18 | creator.lastName, 19 | likeCount 20 | ORDER BY 21 | likeCount DESC, 22 | message.id ASC 23 | LIMIT 100 24 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-13.cypher: -------------------------------------------------------------------------------- 1 | // Q13. Popular Tags per month in a country 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH (:Country {name: $country})<-[:IS_LOCATED_IN]-(message:Message) 6 | OPTIONAL MATCH (message)-[:HAS_TAG]->(tag:Tag) 7 | WITH 8 | message.creationDate/10000000000000 AS year, 9 | message.creationDate/100000000000%100 AS month, 10 | message, 11 | tag 12 | WITH year, month, count(message) AS popularity, tag 13 | ORDER BY popularity DESC, tag.name ASC 14 | WITH 15 | year, 16 | month, 17 | collect([tag.name, popularity]) AS popularTags 18 | WITH 19 | year, 20 | month, 21 | [popularTag IN popularTags WHERE popularTag[0] IS NOT NULL] AS popularTags 22 | RETURN 23 | year, 24 | month, 25 | popularTags[0..5] AS topPopularTags 26 | ORDER BY 27 | year DESC, 28 | month ASC 29 | LIMIT 100 30 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-14.cypher: -------------------------------------------------------------------------------- 1 | // Q14. Top thread initiators 2 | /* 3 | :param { 4 | startDate: 20120531220000000, 5 | endDate: 20120630220000000 6 | } 7 | */ 8 | MATCH (person:Person)<-[:HAS_CREATOR]-(post:Post)<-[:REPLY_OF*0..]-(reply:Message) 9 | WHERE post.creationDate >= $startDate 10 | AND post.creationDate <= $endDate 11 | AND reply.creationDate >= $startDate 12 | AND reply.creationDate <= $endDate 13 | RETURN 14 | person.id, 15 | person.firstName, 16 | person.lastName, 17 | count(DISTINCT post) AS threadCount, 18 | count(DISTINCT reply) AS messageCount 19 | ORDER BY 20 | messageCount DESC, 21 | person.id ASC 22 | LIMIT 100 23 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-15.cypher: -------------------------------------------------------------------------------- 1 | // Q15. Social normals 2 | /* 3 | :param { country: 'Burma' } 4 | */ 5 | MATCH 6 | (country:Country {name: $country}) 7 | MATCH 8 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person1:Person) 9 | OPTIONAL MATCH 10 | // start a new MATCH as friend might live in the same City 11 | // and thus can reuse the IS_PART_OF edge 12 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend1:Person), 13 | (person1)-[:KNOWS]-(friend1) 14 | WITH country, person1, count(friend1) AS friend1Count 15 | WITH country, avg(friend1Count) AS socialNormalFloat 16 | WITH country, floor(socialNormalFloat) AS socialNormal 17 | MATCH 18 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person2:Person) 19 | OPTIONAL MATCH 20 | (country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(friend2:Person)-[:KNOWS]-(person2) 21 | WITH country, person2, count(friend2) AS friend2Count, socialNormal 22 | WHERE friend2Count = socialNormal 23 | RETURN 24 | person2.id, 25 | friend2Count AS count 26 | ORDER BY 27 | person2.id ASC 28 | LIMIT 100 29 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-16.cypher: -------------------------------------------------------------------------------- 1 | // Q16. Experts in social circle 2 | /* 3 | :param { 4 | personId: 19791209310731, 5 | country: 'Pakistan', 6 | tagClass: 'MusicalArtist', 7 | minPathDistance: 3, 8 | maxPathDistance: 5 9 | } 10 | */ 11 | // This query will not work in a browser as is. I tried alternatives approaches, 12 | // e.g. enabling path of arbitrary lengths, saving the path to a variable p and 13 | // checking for `$minPathDistance <= length(p)`, but these could not be 14 | // evaluated due to the excessive amount of paths. 15 | // If you would like to test the query in the browser, replace the values of 16 | // $minPathDistance and $maxPathDistance to a constant. 17 | MATCH 18 | (:Person {id: $personId})-[:KNOWS*$minPathDistance..$maxPathDistance]-(person:Person) 19 | WITH DISTINCT person 20 | MATCH 21 | (person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(:Country {name: $country}), 22 | (person)<-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]-> 23 | (:TagClass {name: $tagClass}) 24 | MATCH 25 | (message)-[:HAS_TAG]->(tag:Tag) 26 | RETURN 27 | person.id, 28 | tag.name, 29 | count(DISTINCT message) AS messageCount 30 | ORDER BY 31 | messageCount DESC, 32 | tag.name ASC, 33 | person.id ASC 34 | LIMIT 100 35 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-17.cypher: -------------------------------------------------------------------------------- 1 | // Q17. Friend triangles 2 | /* 3 | :param { country: 'Spain' } 4 | */ 5 | MATCH (country:Country {name: $country}) 6 | MATCH (a:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 7 | MATCH (b:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 8 | MATCH (c:Person)-[:IS_LOCATED_IN]->(:City)-[:IS_PART_OF]->(country) 9 | MATCH (a)-[:KNOWS]-(b), (b)-[:KNOWS]-(c), (c)-[:KNOWS]-(a) 10 | WHERE a.id < b.id 11 | AND b.id < c.id 12 | RETURN count(*) AS count 13 | // as a less elegant solution, count(a) also works 14 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-18.cypher: -------------------------------------------------------------------------------- 1 | // Q18. How many persons have a given number of posts 2 | /* 3 | :param { 4 | date: 20110722000000000, 5 | lengthThreshold: 20, 6 | languages: ['ar'] 7 | } 8 | */ 9 | MATCH (person:Person) 10 | OPTIONAL MATCH (person)<-[:HAS_CREATOR]-(message:Message)-[:REPLY_OF*0..]->(post:Post) 11 | WHERE message.content IS NOT NULL 12 | AND message.length < $lengthThreshold 13 | AND message.creationDate > $date 14 | AND post.language IN $languages 15 | WITH 16 | person, 17 | count(message) AS messageCount 18 | RETURN 19 | messageCount, 20 | count(person) AS personCount 21 | ORDER BY 22 | personCount DESC, 23 | messageCount DESC 24 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-19.cypher: -------------------------------------------------------------------------------- 1 | // Q19. Stranger's interaction 2 | /* 3 | :param { 4 | date: 19890101, 5 | tagClass1: 'MusicalArtist', 6 | tagClass2: 'OfficeHolder' 7 | } 8 | */ 9 | MATCH 10 | (:TagClass {name: $tagClass1})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 11 | (forum1:Forum)-[:HAS_MEMBER]->(stranger:Person) 12 | WITH DISTINCT stranger 13 | MATCH 14 | (:TagClass {name: $tagClass2})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]- 15 | (forum2:Forum)-[:HAS_MEMBER]->(stranger) 16 | WITH DISTINCT stranger 17 | MATCH 18 | (person:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF*]->(message:Message)-[:HAS_CREATOR]->(stranger) 19 | WHERE person.birthday > $date 20 | AND person <> stranger 21 | AND NOT (person)-[:KNOWS]-(stranger) 22 | AND NOT (message)-[:REPLY_OF*]->(:Message)-[:HAS_CREATOR]->(stranger) 23 | RETURN 24 | person.id, 25 | count(DISTINCT stranger) AS strangersCount, 26 | count(comment) AS interactionCount 27 | ORDER BY 28 | interactionCount DESC, 29 | person.id ASC 30 | LIMIT 100 31 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-2.cypher: -------------------------------------------------------------------------------- 1 | // Q2. Top tags for country, age, gender, time 2 | /* 3 | :param { 4 | date1: 20091231230000000, 5 | date2: 20101107230000000, 6 | country1: 'Ethiopia', 7 | country2: 'Belarus' 8 | } 9 | */ 10 | MATCH 11 | (country:Country)<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]-(person:Person) 12 | <-[:HAS_CREATOR]-(message:Message)-[:HAS_TAG]->(tag:Tag) 13 | WHERE message.creationDate >= $startDate 14 | AND message.creationDate <= $endDate 15 | AND (country.name = $country1 OR country.name = $country2) 16 | WITH 17 | country.name AS countryName, 18 | message.creationDate/100000000000%100 AS month, 19 | person.gender AS gender, 20 | floor((20130101 - person.birthday) / 10000 / 5.0) AS ageGroup, 21 | tag.name AS tagName, 22 | message 23 | WITH 24 | countryName, month, gender, ageGroup, tagName, count(message) AS messageCount 25 | WHERE messageCount > 100 26 | RETURN 27 | countryName, 28 | month, 29 | gender, 30 | ageGroup, 31 | tagName, 32 | messageCount 33 | ORDER BY 34 | messageCount DESC, 35 | tagName ASC, 36 | ageGroup ASC, 37 | gender ASC, 38 | month ASC, 39 | countryName ASC 40 | LIMIT 100 41 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-20.cypher: -------------------------------------------------------------------------------- 1 | // Q20. High-level topics 2 | /* 3 | :param { tagClasses: ['Writer', 'Single', 'Country'] } 4 | */ 5 | UNWIND $tagClasses AS tagClassName 6 | MATCH 7 | (tagClass:TagClass {name: tagClassName})<-[:IS_SUBCLASS_OF*0..]- 8 | (:TagClass)<-[:HAS_TYPE]-(tag:Tag)<-[:HAS_TAG]-(message:Message) 9 | RETURN 10 | tagClass.name, 11 | count(DISTINCT message) AS messageCount 12 | ORDER BY 13 | messageCount DESC, 14 | tagClass.name ASC 15 | LIMIT 100 16 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-23.cypher: -------------------------------------------------------------------------------- 1 | // Q23. Holiday destinations 2 | /* 3 | :param { country: 'Egypt' } 4 | */ 5 | MATCH 6 | (home:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (:Person)<-[:HAS_CREATOR]-(message:Message)-[:IS_LOCATED_IN]->(destination:Country) 8 | WHERE home <> destination 9 | WITH 10 | message, 11 | destination, 12 | message.creationDate/100000000000%100 AS month 13 | RETURN 14 | count(message) AS messageCount, 15 | destination.name, 16 | month 17 | ORDER BY 18 | messageCount DESC, 19 | destination.name ASC, 20 | month ASC 21 | LIMIT 100 22 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-24.cypher: -------------------------------------------------------------------------------- 1 | // Q24. Messages by Topic and Continent 2 | /* 3 | :param { tagClass: 'Single' } 4 | */ 5 | MATCH (:TagClass {name: $tagClass})<-[:HAS_TYPE]-(:Tag)<-[:HAS_TAG]-(message:Message) 6 | WITH DISTINCT message 7 | MATCH (message)-[:IS_LOCATED_IN]->(:Country)-[:IS_PART_OF]->(continent:Continent) 8 | OPTIONAL MATCH (message)<-[like:LIKES]-(:Person) 9 | WITH 10 | message, 11 | message.creationDate/10000000000000 AS year, 12 | message.creationDate/100000000000%100 AS month, 13 | like, 14 | continent 15 | RETURN 16 | count(DISTINCT message) AS messageCount, 17 | count(like) AS likeCount, 18 | year, 19 | month, 20 | continent.name 21 | ORDER BY 22 | year ASC, 23 | month ASC, 24 | continent.name DESC 25 | LIMIT 100 26 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-3.cypher: -------------------------------------------------------------------------------- 1 | // Q3. Tag evolution 2 | /* 3 | :param { 4 | year: 2010, 5 | month: 10 6 | } 7 | */ 8 | WITH 9 | $year AS year1, 10 | $month AS month1, 11 | $year + toInteger($month / 12.0) AS year2, 12 | $month % 12 + 1 AS month2 13 | // year-month 1 14 | MATCH (tag:Tag) 15 | OPTIONAL MATCH (message1:Message)-[:HAS_TAG]->(tag) 16 | WHERE message1.creationDate/10000000000000 = year1 17 | AND message1.creationDate/100000000000%100 = month1 18 | WITH year2, month2, tag, count(message1) AS countMonth1 19 | // year-month 2 20 | OPTIONAL MATCH (message2:Message)-[:HAS_TAG]->(tag) 21 | WHERE message2.creationDate/10000000000000 = year2 22 | AND message2.creationDate/100000000000%100 = month2 23 | WITH 24 | tag, 25 | countMonth1, 26 | count(message2) AS countMonth2 27 | RETURN 28 | tag.name, 29 | countMonth1, 30 | countMonth2, 31 | abs(countMonth1-countMonth2) AS diff 32 | ORDER BY 33 | diff DESC, 34 | tag.name ASC 35 | LIMIT 100 36 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-4.cypher: -------------------------------------------------------------------------------- 1 | // Q4. Popular topics in a country 2 | /* 3 | :param { 4 | tagClass: 'MusicalArtist', 5 | country: 'Burma' 6 | } 7 | */ 8 | MATCH 9 | (:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 10 | (person:Person)<-[:HAS_MODERATOR]-(forum:Forum)-[:CONTAINER_OF]-> 11 | (post:Post)-[:HAS_TAG]->(:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass}) 12 | RETURN 13 | forum.id, 14 | forum.title, 15 | forum.creationDate, 16 | person.id, 17 | count(DISTINCT post) AS postCount 18 | ORDER BY 19 | postCount DESC, 20 | forum.id ASC 21 | LIMIT 20 -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-5.cypher: -------------------------------------------------------------------------------- 1 | // Q5. Top posters in a country 2 | /* 3 | :param { country: 'Belarus' } 4 | */ 5 | MATCH 6 | (:Country {name: $country})<-[:IS_PART_OF]-(:City)<-[:IS_LOCATED_IN]- 7 | (person:Person)<-[:HAS_MEMBER]-(forum:Forum) 8 | WITH forum, count(person) AS numberOfMembers 9 | ORDER BY numberOfMembers DESC, forum.id ASC 10 | LIMIT 100 11 | WITH collect(forum) AS popularForums 12 | UNWIND popularForums AS forum 13 | MATCH 14 | (forum)-[:HAS_MEMBER]->(person:Person) 15 | OPTIONAL MATCH 16 | (person)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(popularForum:Forum) 17 | WHERE popularForum IN popularForums 18 | RETURN 19 | person.id, 20 | person.firstName, 21 | person.lastName, 22 | person.creationDate, 23 | count(DISTINCT post) AS postCount 24 | ORDER BY 25 | postCount DESC, 26 | person.id ASC 27 | LIMIT 100 28 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-6.cypher: -------------------------------------------------------------------------------- 1 | // Q6. Most active Posters of a given Topic 2 | /* 3 | :param { tag: 'Abbas_I_of_Persia' } 4 | */ 5 | MATCH (tag:Tag {name: $tag})<-[:HAS_TAG]-(message:Message)-[:HAS_CREATOR]->(person:Person) 6 | OPTIONAL MATCH (:Person)-[like:LIKES]->(message) 7 | OPTIONAL MATCH (message)<-[:REPLY_OF]-(comment:Comment) 8 | WITH person, count(DISTINCT like) AS likeCount, count(DISTINCT comment) AS replyCount, count(DISTINCT message) AS messageCount 9 | RETURN 10 | person.id, 11 | replyCount, 12 | likeCount, 13 | messageCount, 14 | 1*messageCount + 2*replyCount + 10*likeCount AS score 15 | ORDER BY 16 | score DESC, 17 | person.id ASC 18 | LIMIT 100 19 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-7.cypher: -------------------------------------------------------------------------------- 1 | // Q7. Most authoritative users on a given topic 2 | /* 3 | :param { tag: 'Arnold_Schwarzenegger' } 4 | */ 5 | MATCH (tag:Tag {name: $tag}) 6 | MATCH (tag)<-[:HAS_TAG]-(message1:Message)-[:HAS_CREATOR]->(person1:Person) 7 | MATCH (tag)<-[:HAS_TAG]-(message2:Message)-[:HAS_CREATOR]->(person1) 8 | OPTIONAL MATCH (message2)<-[:LIKES]-(person2:Person) 9 | OPTIONAL MATCH (person2)<-[:HAS_CREATOR]-(message3:Message)<-[like:LIKES]-(p3:Person) 10 | RETURN 11 | person1.id, 12 | count(DISTINCT like) AS authorityScore 13 | ORDER BY 14 | authorityScore DESC, 15 | person1.id ASC 16 | LIMIT 100 17 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-8.cypher: -------------------------------------------------------------------------------- 1 | // Q8. Related Topics 2 | /* 3 | :param { tag: 'Genghis_Khan' } 4 | */ 5 | MATCH 6 | (tag:Tag {name: $tag})<-[:HAS_TAG]-(message:Message), 7 | (message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_TAG]->(relatedTag:Tag) 8 | WHERE NOT (comment)-[:HAS_TAG]->(tag) 9 | RETURN 10 | relatedTag.name, 11 | count(DISTINCT comment) AS count 12 | ORDER BY 13 | count DESC, 14 | relatedTag.name ASC 15 | LIMIT 100 16 | -------------------------------------------------------------------------------- /neo4j/queries/temp/bi-9.cypher: -------------------------------------------------------------------------------- 1 | // Q9. Forum with related Tags 2 | /* 3 | :param { 4 | tagClass1: 'BaseballPlayer', 5 | tagClass2: 'ChristianBishop', 6 | threshold: 200 7 | } 8 | */ 9 | MATCH 10 | (forum:Forum)-[:HAS_MEMBER]->(person:Person) 11 | WITH forum, count(person) AS members 12 | WHERE members > $threshold 13 | MATCH 14 | (forum)-[:CONTAINER_OF]->(post1:Post)-[:HAS_TAG]-> 15 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass1}) 16 | WITH forum, count(DISTINCT post1) AS count1 17 | MATCH 18 | (forum)-[:CONTAINER_OF]->(post2:Post)-[:HAS_TAG]-> 19 | (:Tag)-[:HAS_TYPE]->(:TagClass {name: $tagClass2}) 20 | WITH forum, count1, count(DISTINCT post2) AS count2 21 | RETURN 22 | forum.id, 23 | count1, 24 | count2 25 | ORDER BY 26 | abs(count2-count1) DESC, 27 | forum.id ASC 28 | LIMIT 100 29 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[path:KNOWS*1..3]-(friend:Person) 2 | WHERE friend.firstName = $firstName 3 | WITH friend, min(length(path)) AS distance 4 | ORDER BY distance ASC, friend.lastName ASC, toInteger(friend.id) ASC 5 | LIMIT 20 6 | MATCH (friend)-[:IS_LOCATED_IN]->(friendCity:Place) 7 | OPTIONAL MATCH (friend)-[studyAt:STUDY_AT]->(uni:Organisation)-[:IS_LOCATED_IN]->(uniCity:Place) 8 | WITH 9 | friend, 10 | collect( 11 | CASE uni.name 12 | WHEN null THEN null 13 | ELSE [uni.name, studyAt.classYear, uniCity.name] 14 | END 15 | ) AS unis, 16 | friendCity, 17 | distance 18 | OPTIONAL MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(companyCountry:Place) 19 | WITH 20 | friend, 21 | collect( 22 | CASE company.name 23 | WHEN null THEN null 24 | ELSE [company.name, workAt.workFrom, companyCountry.name] 25 | END 26 | ) AS companies, 27 | unis, 28 | friendCity, 29 | distance 30 | RETURN 31 | friend.id AS friendId, 32 | friend.lastName AS friendLastName, 33 | distance AS distanceFromPerson, 34 | friend.birthday AS friendBirthday, 35 | friend.creationDate AS friendCreationDate, 36 | friend.gender AS friendGender, 37 | friend.browserUsed AS friendBrowserUsed, 38 | friend.locationIP AS friendLocationIp, 39 | friend.email AS friendEmails, 40 | friend.speaks AS friendLanguages, 41 | friendCity.name AS friendCityName, 42 | unis AS friendUniversities, 43 | companies AS friendCompanies 44 | ORDER BY distanceFromPerson ASC, friendLastName ASC, toInteger(friendId) ASC 45 | LIMIT 20 46 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-10-without-list-comprehension.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post)+[null] AS posts, count(post) AS postCount, person 10 | UNWIND posts AS commonPostCandidate 11 | WITH 12 | friend, 13 | city, 14 | commonPostCandidate, 15 | postCount, 16 | person 17 | WHERE (commonPostCandidate)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person) OR commonPostCandidate IS NULL 18 | WITH 19 | friend, 20 | city, 21 | postCount, 22 | count(commonPostCandidate) AS commonPostCount 23 | RETURN 24 | friend.id AS personId, 25 | friend.firstName AS personFirstName, 26 | friend.lastName AS personLastName, 27 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 28 | commonPostCount, 29 | postCount, 30 | friend.gender AS personGender, 31 | city.name AS personCityName 32 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 33 | LIMIT 10 34 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-10.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*2..2]-(friend:Person)-[:IS_LOCATED_IN]->(city:Place) 2 | WHERE 3 | ((friend.birthday/100%100 = $month AND friend.birthday%100 >= 21) OR 4 | (friend.birthday/100%100 = $nextMonth AND friend.birthday%100 < 22)) 5 | AND not(friend=person) 6 | AND not((friend)-[:KNOWS]-(person)) 7 | WITH DISTINCT friend, city, person 8 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post) 9 | WITH friend, city, collect(post) AS posts, person 10 | WITH 11 | friend, 12 | city, 13 | length(posts) AS postCount, 14 | length([p IN posts WHERE (p)-[:HAS_TAG]->(:Tag)<-[:HAS_INTEREST]-(person)]) AS commonPostCount 15 | RETURN 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | commonPostCount - (postCount - commonPostCount) AS commonInterestScore, 20 | friend.gender AS personGender, 21 | city.name AS personCityName 22 | ORDER BY commonInterestScore DESC, toInteger(personId) ASC 23 | LIMIT 10 24 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-11.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person) 2 | WHERE not(person=friend) 3 | WITH DISTINCT friend 4 | MATCH (friend)-[workAt:WORK_AT]->(company:Organisation)-[:IS_LOCATED_IN]->(:Place {name:$countryName}) 5 | WHERE workAt.workFrom < $workFromYear 6 | RETURN 7 | friend.id AS personId, 8 | friend.firstName AS personFirstName, 9 | friend.lastName AS personLastName, 10 | company.name AS organizationName, 11 | workAt.workFrom AS organizationWorkFromYear 12 | ORDER BY organizationWorkFromYear ASC, toInteger(personId) ASC, organizationName DESC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-12.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(comment:Comment)-[:REPLY_OF]->(:Post)-[:HAS_TAG]->(tag:Tag), 2 | (tag)-[:HAS_TYPE]->(tagClass:TagClass)-[:IS_SUBCLASS_OF*0..]->(baseTagClass:TagClass) 3 | WHERE tagClass.name = $tagClassName OR baseTagClass.name = $tagClassName 4 | RETURN 5 | friend.id AS personId, 6 | friend.firstName AS personFirstName, 7 | friend.lastName AS personLastName, 8 | collect(DISTINCT tag.name) AS tagNames, 9 | count(DISTINCT comment) AS replyCount 10 | ORDER BY replyCount DESC, toInteger(personId) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-13.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person1:Person {id:$person1Id}), (person2:Person {id:$person2Id}) 2 | OPTIONAL MATCH path = shortestPath((person1)-[:KNOWS*]-(person2)) 3 | RETURN 4 | CASE path IS NULL 5 | WHEN true THEN -1 6 | ELSE length(path) 7 | END AS shortestPathLength; 8 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-14.cypher: -------------------------------------------------------------------------------- 1 | MATCH path = allShortestPaths((person1:Person {id:$person1Id})-[:KNOWS*..15]-(person2:Person {id:$person2Id})) 2 | WITH nodes(path) AS pathNodes 3 | RETURN 4 | extract(n IN pathNodes | n.id) AS personIdsInPath, 5 | reduce(weight=0.0, idx IN range(1,size(pathNodes)-1) | extract(prev IN [pathNodes[idx-1]] | extract(curr IN [pathNodes[idx]] | weight + length((curr)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(prev))*1.0 + length((prev)<-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]->(:Post)-[:HAS_CREATOR]->(curr))*1.0 + length((prev)-[:HAS_CREATOR]-(:Comment)-[:REPLY_OF]-(:Comment)-[:HAS_CREATOR]-(curr))*0.5) )[0][0]) AS pathWight 6 | ORDER BY pathWight DESC 7 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate <= $maxDate 3 | RETURN 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS postOrCommentId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS postOrCommentContent, 12 | message.creationDate AS postOrCommentCreationDate 13 | ORDER BY postOrCommentCreationDate DESC, toInteger(postOrCommentId) ASC 14 | LIMIT 20 15 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(messageX:Message), 2 | (messageX)-[:IS_LOCATED_IN]->(countryX:Place) 3 | WHERE 4 | not(person=friend) 5 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryX)) 6 | AND countryX.name=$countryXName AND messageX.creationDate>=$startDate 7 | AND messageX.creationDate<$endDate 8 | WITH friend, count(DISTINCT messageX) AS xCount 9 | MATCH (friend)<-[:HAS_CREATOR]-(messageY:Message)-[:IS_LOCATED_IN]->(countryY:Place) 10 | WHERE 11 | countryY.name=$countryYName 12 | AND not((friend)-[:IS_LOCATED_IN]->()-[:IS_PART_OF]->(countryY)) 13 | AND messageY.creationDate>=$startDate 14 | AND messageY.creationDate<$endDate 15 | WITH 16 | friend.id AS personId, 17 | friend.firstName AS personFirstName, 18 | friend.lastName AS personLastName, 19 | xCount, 20 | count(DISTINCT messageY) AS yCount 21 | RETURN 22 | personId, 23 | personFirstName, 24 | personLastName, 25 | xCount, 26 | yCount, 27 | xCount + yCount AS count 28 | ORDER BY count DESC, toInteger(personId) ASC 29 | LIMIT 20 30 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS]-(:Person)<-[:HAS_CREATOR]-(post:Post)-[:HAS_TAG]->(tag:Tag) 2 | WHERE post.creationDate >= $startDate 3 | AND post.creationDate < $endDate 4 | WITH person, count(post) AS postsOnTag, tag 5 | OPTIONAL MATCH (person)-[:KNOWS]-()<-[:HAS_CREATOR]-(oldPost:Post)-[:HAS_TAG]->(tag) 6 | WHERE oldPost.creationDate < $startDate 7 | WITH person, postsOnTag, tag, count(oldPost) AS cp 8 | WHERE cp = 0 9 | RETURN 10 | tag.name AS tagName, 11 | sum(postsOnTag) AS postCount 12 | ORDER BY postCount DESC, tagName ASC 13 | LIMIT 10 14 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[membership:HAS_MEMBER]-(forum:Forum) 2 | WHERE membership.joinDate>$minDate 3 | AND not(person=friend) 4 | WITH DISTINCT friend, forum 5 | OPTIONAL MATCH (friend)<-[:HAS_CREATOR]-(post:Post)<-[:CONTAINER_OF]-(forum) 6 | WITH forum, count(post) AS postCount 7 | RETURN 8 | forum.title AS forumTitle, 9 | postCount 10 | ORDER BY postCount DESC, toInteger(forum.id) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (person:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person), 3 | (friend)<-[:HAS_CREATOR]-(friendPost:Post)-[:HAS_TAG]->(knownTag:Tag {name:$tagName}) 4 | WHERE not(person=friend) 5 | MATCH (friendPost)-[:HAS_TAG]->(commonTag:Tag) 6 | WHERE not(commonTag=knownTag) 7 | WITH DISTINCT commonTag, knownTag, friend 8 | MATCH (commonTag)<-[:HAS_TAG]-(commonPost:Post)-[:HAS_TAG]->(knownTag) 9 | WHERE (commonPost)-[:HAS_CREATOR]->(friend) 10 | RETURN 11 | commonTag.name AS tagName, 12 | count(commonPost) AS postCount 13 | ORDER BY postCount DESC, tagName ASC 14 | LIMIT 10 15 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-7-with-lists.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})<-[:HAS_CREATOR]-(message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | collect([message, likeTime]) AS latestLikes, 7 | person 8 | WITH 9 | liker, 10 | head(latestLikes) AS latestLike, 11 | person 12 | RETURN 13 | liker.id AS personId, 14 | liker.firstName AS personFirstName, 15 | liker.lastName AS personLastName, 16 | latestLike[1] AS likeCreationDate, 17 | latestLike[0].id AS commentOrPostId, 18 | CASE exists(latestLike[0].content) 19 | WHEN true THEN latestLike[0].content 20 | ELSE latestLike[0].imageFile 21 | END AS commentOrPostContent, 22 | latestLike[0].creationDate AS commentOrPostCreationDate, 23 | not((liker)-[:KNOWS]-(person)) AS isNew 24 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 25 | LIMIT 20 26 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId})<-[:HAS_CREATOR]-(message:Message)<-[like:LIKES]-(liker:Person) 2 | WITH liker, message, like.creationDate AS likeTime, person 3 | ORDER BY likeTime DESC, toInteger(message.id) ASC 4 | WITH 5 | liker, 6 | head(collect({msg: message, likeTime: likeTime})) AS latestLike, 7 | person 8 | RETURN 9 | liker.id AS personId, 10 | liker.firstName AS personFirstName, 11 | liker.lastName AS personLastName, 12 | latestLike.likeTime AS likeCreationDate, 13 | latestLike.msg.id AS commentOrPostId, 14 | CASE exists(latestLike.msg.content) 15 | WHEN true THEN latestLike.msg.content 16 | ELSE latestLike.msg.imageFile 17 | END AS commentOrPostContent, 18 | latestLike.msg.creationDate AS commentOrPostCreationDate, 19 | not((liker)-[:KNOWS]-(person)) AS isNew 20 | ORDER BY likeCreationDate DESC, toInteger(personId) ASC 21 | LIMIT 20 22 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (start:Person {id:$personId})<-[:HAS_CREATOR]-(:Message)<-[:REPLY_OF]-(comment:Comment)-[:HAS_CREATOR]->(person:Person) 3 | RETURN 4 | person.id AS personId, 5 | person.firstName AS personFirstName, 6 | person.lastName AS personLastName, 7 | comment.creationDate AS commentCreationDate, 8 | comment.id AS commentId, 9 | comment.content AS commentContent 10 | ORDER BY commentCreationDate DESC, toInteger(commentId) ASC 11 | LIMIT 20 12 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-complex-9.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})-[:KNOWS*1..2]-(friend:Person)<-[:HAS_CREATOR]-(message:Message) 2 | WHERE message.creationDate < $maxDate 3 | RETURN DISTINCT 4 | friend.id AS personId, 5 | friend.firstName AS personFirstName, 6 | friend.lastName AS personLastName, 7 | message.id AS commentOrPostId, 8 | CASE exists(message.content) 9 | WHEN true THEN message.content 10 | ELSE message.imageFile 11 | END AS commentOrPostContent, 12 | message.creationDate AS commentOrPostCreationDate 13 | ORDER BY message.creationDate DESC, toInteger(message.id) ASC 14 | LIMIT 20 15 | 16 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:$personId})-[:IS_LOCATED_IN]->(p:Place) 2 | RETURN 3 | n.firstName AS firstName, 4 | n.lastName AS lastName, 5 | n.birthday AS birthday, 6 | n.locationIP AS locationIP, 7 | n.browserUsed AS browserUsed, 8 | p.id AS cityId, 9 | n.gender AS gender, 10 | n.creationDate AS creationDate 11 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (:Person {id:$personId})<-[:HAS_CREATOR]-(m:Message)-[:REPLY_OF*0..]->(p:Post) 2 | MATCH (p)-[:HAS_CREATOR]->(c) 3 | RETURN 4 | m.id as messageId, 5 | CASE exists(m.content) 6 | WHEN true THEN m.content 7 | ELSE m.imageFile 8 | END AS messageContent, 9 | m.creationDate AS messageCreationDate, 10 | p.id AS originalPostId, 11 | c.id AS originalPostAuthorId, 12 | c.firstName as originalPostAuthorFirstName, 13 | c.lastName as originalPostAuthorLastName 14 | ORDER BY messageCreationDate DESC 15 | LIMIT 10 16 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (n:Person {id:$personId})-[r:KNOWS]-(friend) RETURN friend.id AS personId, friend.firstName AS firstName, friend.lastName AS lastName, r.creationDate AS friendshipCreationDate ORDER BY friendshipCreationDate DESC, toInteger(personId) ASC 2 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId}) RETURN m.creationDate as messageCreationDate, CASE exists(m.content) WHEN true THEN m.content ELSE m.imageFile END AS messageContent 2 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})-[:HAS_CREATOR]->(p:Person) RETURN p.id AS personId, p.firstName AS firstName, p.lastName AS lastName 2 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})-[:REPLY_OF*0..]->(p:Post)<-[:CONTAINER_OF]-(f:Forum)-[:HAS_MODERATOR]->(mod:Person) RETURN f.id AS forumId, f.title AS forumTitle, mod.id AS moderatorId, mod.firstName AS moderatorFirstName, mod.lastName AS moderatorLastName 2 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-short-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH (m:Message {id:$messageId})<-[:REPLY_OF]-(c:Comment)-[:HAS_CREATOR]->(p:Person) OPTIONAL MATCH (m)-[:HAS_CREATOR]->(a:Person)-[r:KNOWS]-(p) RETURN c.id AS commentId, c.content AS commentContent, c.creationDate AS commentCreationDate, p.id AS replyAuthorId, p.firstName AS replyAuthorFirstName, p.lastName AS replyAuthorLastName, CASE r WHEN null THEN false ELSE true END AS replyAuthorKnowsOriginalMessageAuthor ORDER BY commentCreationDate DESC, replyAuthorId 2 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-1.cypher: -------------------------------------------------------------------------------- 1 | MATCH (c:City {id:$cityId}) 2 | CREATE (p:Person {id: $personId, firstName: $personFirstName, lastName: $personLastName, gender: $gender, birthday: $birthday, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, speaks: $languages, emails: $emails})-[:IS_LOCATED_IN]->(c) 3 | WITH p, count(*) AS dummy1 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_INTEREST]->(t) 7 | WITH p, count(*) AS dummy2 8 | UNWIND $studyAt AS s 9 | MATCH (u:Organisation {id: s[0]}) 10 | CREATE (p)-[:STUDY_AT {classYear: s[1]}]->(u) 11 | WITH p, count(*) AS dummy3 12 | UNWIND $workAt AS w 13 | MATCH (comp:Organisation {id: w[0]}) 14 | CREATE (p)-[:WORKS_AT {workFrom: w[1]}]->(comp) 15 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-2.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(post:Post {id:$postId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(post) 3 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-3.cypher: -------------------------------------------------------------------------------- 1 | MATCH (person:Person {id:$personId}),(comment:Comment {id:$commentId}) 2 | CREATE (person)-[:LIKES {creationDate:$creationDate}]->(comment) 3 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-4.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p:Person {id: $moderatorPersonId}) 2 | CREATE (f:Forum {id: $forumId, title: $forumTitle, creationDate: $creationDate})-[:HAS_MODERATOR]->(p) 3 | WITH f 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (f)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-5.cypher: -------------------------------------------------------------------------------- 1 | MATCH (f:Forum {id:$forumId}), (p:Person {id:$personId}) 2 | CREATE (f)-[:HAS_MEMBER {joinDate:$joinDate}]->(p) 3 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-6.cypher: -------------------------------------------------------------------------------- 1 | MATCH (author:Person {id: $authorPersonId}), (country:Country {id: $countryId}), (forum:Forum {id: $forumId}) 2 | CREATE (author)<-[:HAS_CREATOR]-(p:Post:Message {id: $postId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: CASE $content WHEN '' THEN null ELSE $content END, imageFile: CASE $imageFile WHEN '' THEN null ELSE $imageFile END, length: $length})<-[:CONTAINER_OF]-(forum), (p)-[:IS_LOCATED_IN]->(country) 3 | WITH p 4 | UNWIND $tagIds AS tagId 5 | MATCH (t:Tag {id: tagId}) 6 | CREATE (p)-[:HAS_TAG]->(t) 7 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-7.cypher: -------------------------------------------------------------------------------- 1 | MATCH 2 | (author:Person {id: $authorPersonId}), 3 | (country:Country {id: $countryId}), 4 | (message:Message {id: CASE $replyToPostId WHEN -1 THEN $replyToCommentId ELSE $replyToPostId END}) 5 | CREATE (author)<-[:HAS_CREATOR]-(c:Comment:Message {id: $commentId, creationDate: $creationDate, locationIP: $locationIP, browserUsed: $browserUsed, content: $content, length: $length})-[:REPLY_OF]->(message), (c)-[:IS_LOCATED_IN]->(country) 6 | WITH c 7 | UNWIND $tagIds AS tagId 8 | MATCH (t:Tag {id: tagId}) 9 | CREATE (c)-[:HAS_TAG]->(t) 10 | -------------------------------------------------------------------------------- /neo4j/queries/temp/interactive-update-8.cypher: -------------------------------------------------------------------------------- 1 | MATCH (p1:Person {id:$person1Id}), (p2:Person {id:$person2Id}) 2 | CREATE (p1)-[:KNOWS {creationDate:$creationDate}]->(p2) 3 | -------------------------------------------------------------------------------- /neo4j/quick-switch.sh: -------------------------------------------------------------------------------- 1 | db=$1 2 | NEO4J_DB_DIR=$NEO4J_HOME/data/databases/$db.db 3 | 4 | $NEO4J_HOME/bin/neo4j stop 5 | 6 | rm -rf $NEO4J_HOME/data/databases/graph.db 7 | ln -s $NEO4J_HOME/data/databases/"$db".db $NEO4J_HOME/data/databases/graph.db 8 | 9 | $NEO4J_HOME/bin/neo4j start 10 | 11 | -------------------------------------------------------------------------------- /neo4j/restart-neo4j.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $NEO4J_HOME/bin/neo4j restart 4 | -------------------------------------------------------------------------------- /neo4j/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | ./run_node_1.sh ${db_name} ${num_test} 6 | ./run_node_2.sh ${db_name} ${num_test} 7 | ./run_node_3.sh ${db_name} ${num_test} 8 | ./run_node_4.sh ${db_name} ${num_test} 9 | ./run_node_5.sh ${db_name} ${num_test} 10 | ./run_node_6.sh ${db_name} ${num_test} 11 | ./run_node_7.sh ${db_name} ${num_test} 12 | ./run_node_8.sh ${db_name} ${num_test} 13 | 14 | -------------------------------------------------------------------------------- /neo4j/run_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | ./run_i_short.sh $db_name $num_test 6 | ./run_i_complex.sh $db_name $num_test 7 | ./run_bi.sh $db_name $num_test 8 | -------------------------------------------------------------------------------- /neo4j/run_all_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | ssh node1 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_1.sh ${db_name} ${num_test}" & 6 | ssh node2 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_2.sh ${db_name} ${num_test}" & 7 | #ssh node3 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_3.sh ${db_name} ${num_test}" & 8 | #ssh node4 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_4.sh ${db_name} ${num_test}" & 9 | #ssh node5 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_5.sh ${db_name} ${num_test}" & 10 | #ssh node6 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_6.sh ${db_name} ${num_test}" & 11 | #ssh node7 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_7.sh ${db_name} ${num_test}" & 12 | #ssh node8 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_8.sh ${db_name} ${num_test}" & 13 | 14 | 15 | -------------------------------------------------------------------------------- /neo4j/run_i_complex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python i_complex_1.py snb_1 30786325583618 Carmen 2 3 | python i_complex_2.py snb_1 17592186052613 20121127160000 2 4 | python i_complex_3.py snb_1 17592186055119 20110531170000 42 'Laos' 'Scotland' 2 5 | python i_complex_4.py snb_1 21990232559429 20120430170000 37 2 6 | python i_complex_5.py snb_1 17592186055119 20120926170000 2 7 | python i_complex_6.py snb_1 30786325583618 Angola 2 8 | python i_complex_7.py snb_1 17592186053137 2 9 | python i_complex_8.py snb_1 24189255818757 2 10 | python i_complex_9.py snb_1 13194139542834 20111216160000 2 11 | python i_complex_10.py snb_1 30786325583618 11 2 12 | python i_complex_11.py snb_1 30786325583618 Laos 2010 2 13 | python i_complex_12.py snb_1 17592186052613 BasketballPlayer 2 14 | python i_complex_13.py snb_1 17592186055119 8796093025131 2 15 | python i_complex_14.py snb_1 17592186055119 10995116282665 2 16 | -------------------------------------------------------------------------------- /neo4j/run_i_short.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | python i_short_1.py snb_1 30786325583618 1 4 | python i_short_2.py snb_1 30786325583618 1 5 | python i_short_3.py snb_1 30786325583618 1 6 | python i_short_4.py snb_1 1236950581248 1 7 | python i_short_5.py snb_1 1236950581248 1 8 | python i_short_6.py snb_1 1236950581248 1 9 | python i_short_7.py snb_1 1236950581248 1 10 | -------------------------------------------------------------------------------- /neo4j/run_ic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #./run_i_complex.sh snb_1 3 3 | db_name=$1 4 | num_test=$2 5 | 6 | python i_complex_1.py $db_name 30786325583618 Carmen $num_test > ./result/ic_1.out 7 | python i_complex_2.py $db_name 17592186052613 20121127160000 $num_test > ./result/ic_2.out 8 | python i_complex_3.py $db_name 17592186055119 20110531170000 42 'Laos' 'Scotland' $num_test > ./result/ic_3.out 9 | python i_complex_4.py $db_name 21990232559429 20120430170000 37 $num_test > ./result/ic_4.out 10 | python i_complex_5.py $db_name 17592186055119 20120926170000 $num_test > ./result/ic_5.out 11 | python i_complex_6.py $db_name 30786325583618 Angola $num_test > ./result/ic_6.out 12 | python i_complex_7.py $db_name 17592186053137 $num_test > ./result/ic_7.out 13 | python i_complex_8.py $db_name 24189255818757 $num_test > ./result/ic_8.out 14 | python i_complex_9.py $db_name 13194139542834 20111216160000 $num_test > ./result/ic_9.out 15 | python i_complex_10.py $db_name 30786325583618 11 $num_test > ./result/ic_10.out 16 | python i_complex_11.py $db_name 30786325583618 Laos 2010 $num_test > ./result/ic_11.out 17 | python i_complex_12.py $db_name 17592186052613 BasketballPlayer $num_test > ./result/ic_12.out 18 | python i_complex_13.py $db_name 17592186055119 8796093025131 $num_test > ./result/ic_13.out 19 | python i_complex_14.py $db_name 17592186055119 10995116282665 $num_test > ./result/ic_14.out 20 | 21 | -------------------------------------------------------------------------------- /neo4j/run_is.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | python i_short_1.py $db_name 30786325583618 $num_test > ./result/is_1.out 6 | python i_short_2.py $db_name 30786325583618 $num_test > ./result/is_2.out 7 | python i_short_3.py $db_name 30786325583618 $num_test > ./result/is_3.out 8 | python i_short_4.py $db_name 1236950581248 $num_test > ./result/is_4.out 9 | python i_short_5.py $db_name 1236950581248 $num_test > ./result/is_5.out 10 | python i_short_6.py $db_name 1236950581248 $num_test > ./result/is_6.out 11 | python i_short_7.py $db_name 1236950581248 $num_test > ./result/is_7.out 12 | -------------------------------------------------------------------------------- /neo4j/run_node_1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | timeout 18000s python i_short_1.py $db_name 17592186053137 $num_test > ./result/is_1.out 11 | timeout 18000s python i_complex_2.py $db_name 17592186052613 20120501000000000 $num_test > ./result/ic_2.out 12 | timeout 18000s python i_complex_10.py $db_name 30786325583618 11 $num_test > ./result/ic_10.out 13 | timeout 18000s python bi_4.py $db_name 'MusicalArtist' 'Burma' $num_test > ./result/bi_4.out 14 | timeout 18000s python bi_20.py $db_name "['Writer', 'Single', 'Country']" $num_test > ./result/bi_20.out 15 | timeout 18000s python bi_7.py $db_name Arnold_Schwarzenegger $num_test > ./result/bi_7.out 16 | -------------------------------------------------------------------------------- /neo4j/run_node_2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | timeout 18000s python i_short_2.py $db_name 17592186053137 $num_test > ./result/is_2.out 11 | timeout 18000s python i_complex_3.py $db_name 17592186055119 20120501000000000 42000000000 'Laos' 'Scotland' $num_test > ./result/ic_3.out 12 | timeout 18000s python i_complex_11.py $db_name 30786325583618 Laos 2010 $num_test > ./result/ic_11.out 13 | timeout 18000s python bi_5.py $db_name 'Belarus' $num_test > ./result/bi_5.out 14 | timeout 18000s python bi_13.py $db_name Burma $num_test > ./result/bi_13.out 15 | timeout 18000s python bi_21.py $db_name Ethiopia 2012050100000000 $num_test > ./result/bi_21.out 16 | 17 | -------------------------------------------------------------------------------- /neo4j/run_node_3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | timeout 18000s python i_short_3.py $db_name 17592186053137 $num_test > ./result/is_3.out 11 | timeout 18000s python i_complex_4.py $db_name 21990232559429 20120501000000000 37000000000 $num_test > ./result/ic_4.out 12 | timeout 18000s python i_complex_12.py $db_name 17592186052613 BasketballPlayer $num_test > ./result/ic_12.out 13 | timeout 18000s python bi_6.py $db_name Abbas_I_of_Persia $num_test > ./result/bi_6.out 14 | timeout 18000s python bi_14.py $db_name 20120501000000000 20120604172000000 $num_test > ./result/bi_14.out 15 | timeout 18000s python bi_22.py $db_name Mexico Indonesia $num_test > ./result/bi_22.out 16 | 17 | -------------------------------------------------------------------------------- /neo4j/run_node_4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | #snb1: timeout 18000s python i_short_4.py $db_name 2061586500241 $num_test > ./result/is_4.out 11 | #snb10: timeout 18000s python i_short_4.py $db_name 4947802324994 $num_test > ./result/is_4.out 12 | timeout 18000s python i_short_4.py $db_name 2061586500241 $num_test > ./result/is_4.out 13 | timeout 18000s python i_complex_5.py $db_name 17592186055119 20120501000000000 $num_test > ./result/ic_5.out 14 | timeout 18000s python i_complex_13.py $db_name 8796093030404 26388279074461 $num_test > ./result/ic_13.out 15 | timeout 18000s python bi_8.py $db_name Genghis_Khan $num_test > ./result/bi_8.out 16 | timeout 18000s python bi_16.py $db_name 19791209310731 Pakistan MusicalArtist 3 5 $num_test > ./result/bi_16.out 17 | timeout 18000s python bi_24.py $db_name Single $num_test > ./result/bi_24.out 18 | 19 | -------------------------------------------------------------------------------- /neo4j/run_node_5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | #snb1: timeout 18000s python i_short_5.py $db_name 2061586500241 $num_test > ./result/is_5.out 11 | #snb10: timeout 18000s python i_short_5.py $db_name 4947802324994 $num_test > ./result/is_5.out 12 | timeout 18000s python i_short_5.py $db_name 4947802324994 $num_test > ./result/is_5.out 13 | timeout 18000s python i_complex_6.py $db_name 30786325583618 Angola $num_test > ./result/ic_6.out 14 | timeout 18000s python i_complex_14.py $db_name 8796093030404 26388279074461 $num_test > ./result/ic_14.out 15 | timeout 18000s python bi_15.py $db_name Burma $num_test > ./result/bi_15.out 16 | timeout 18000s python bi_23.py $db_name Egypt $num_test > ./result/bi_23.out 17 | timeout 18000s python bi_12.py $db_name 20120501000000000 400 $num_test > ./result/bi_12.out 18 | 19 | -------------------------------------------------------------------------------- /neo4j/run_node_6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | #snb1: timeout 18000s python i_short_6.py $db_name 2061586500241 $num_test > ./result/is_6.out 11 | #snb10: timeout 18000s python i_short_6.py $db_name 4947802324994 $num_test > ./result/is_6.out 12 | timeout 18000s python i_short_6.py $db_name 2061586500241 $num_test > ./result/is_6.out 13 | timeout 18000s python i_complex_7.py $db_name 17592186053137 $num_test > ./result/ic_7.out 14 | timeout 18000s python bi_1.py $db_name 20120501000000000 $num_test > ./result/bi_1.out 15 | timeout 18000s python bi_9.py $db_name BaseballPlayer ChristianBishop 200 $num_test > ./result/bi_9.out 16 | timeout 18000s python bi_17.py $db_name Spain $num_test > ./result/bi_17.out 17 | timeout 18000s python bi_25.py $db_name 21990232557814 28587302324583 20120401000000000 20120501000000000 $num_test > ./result/bi_25.out 18 | 19 | -------------------------------------------------------------------------------- /neo4j/run_node_7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | #snb1: timeout 18000s python i_short_7.py $db_name 2061586500241 $num_test > ./result/is_7.out 11 | #snb10: timeout 18000s python i_short_7.py $db_name 8246337208329 $num_test > ./result/is_7.out 12 | timeout 18000s python i_short_7.py $db_name 2061586500241 $num_test > ./result/is_7.out 13 | timeout 18000s python i_complex_8.py $db_name 24189255818757 $num_test > ./result/ic_8.out 14 | timeout 18000s python bi_2.py $db_name 20080318008053020 20120524003033020 Spain Germany $num_test > ./result/bi_2.out 15 | timeout 18000s python bi_18.py $db_name 19701026023006040 1000 "['ar']" $num_test > ./result/bi_18.out 16 | timeout 18000s python bi_10.py $db_name John_Rhys-Davies 19701026023006040 $num_test > ./result/bi_10.out 17 | 18 | -------------------------------------------------------------------------------- /neo4j/run_node_8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | db_name=$1 4 | num_test=$2 5 | 6 | #path='graph_database_benchmark/neo4j/' 7 | #cd $path 8 | 9 | 10 | timeout 18000s python i_complex_1.py $db_name 30786325583618 Carmen $num_test > ./result/ic_1.out 11 | timeout 18000s python i_complex_9.py $db_name 13194139542834 20120524003033020 $num_test > ./result/ic_9.out 12 | timeout 18000s python bi_3.py $db_name 2010 10 $num_test > ./result/bi_3.out 13 | timeout 18000s python bi_11.py $db_name Germany "['also', 'Pope', 'that', 'James', 'Henry', 'one', 'Green']" $num_test > ./result/bi_11.out 14 | timeout 18000s python bi_19.py $db_name 19700101005031030 MusicalArtist OfficeHolder $num_test > ./result/bi_19.out 15 | 16 | -------------------------------------------------------------------------------- /neo4j/run_node_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | ssh node1 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_1.sh ${db_name} ${num_test}" & 6 | ssh node2 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_2.sh ${db_name} ${num_test}" & 7 | ssh node3 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_3.sh ${db_name} ${num_test}" & 8 | ssh node4 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_4.sh ${db_name} ${num_test}" & 9 | ssh node5 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_5.sh ${db_name} ${num_test}" & 10 | ssh node6 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_6.sh ${db_name} ${num_test}" & 11 | ssh node7 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_7.sh ${db_name} ${num_test}" & 12 | ssh node8 "/home/zhiyi/graph_database_benchmark/neo4j/run_node_8.sh ${db_name} ${num_test}" & 13 | 14 | 15 | -------------------------------------------------------------------------------- /neo4j/run_node_onepass.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | db_name=$1 3 | num_test=$2 4 | 5 | ./run_node_1.sh ${db_name} ${num_test} 6 | ./run_node_2.sh ${db_name} ${num_test} 7 | ./run_node_3.sh ${db_name} ${num_test} 8 | ./run_node_4.sh ${db_name} ${num_test} 9 | ./run_node_5.sh ${db_name} ${num_test} 10 | ./run_node_6.sh ${db_name} ${num_test} 11 | ./run_node_7.sh ${db_name} ${num_test} 12 | ./run_node_8.sh ${db_name} ${num_test} 13 | 14 | -------------------------------------------------------------------------------- /neo4j/show-size.sh: -------------------------------------------------------------------------------- 1 | . ./path.sh 2 | du -sb $NEO4J_DB_DIR 3 | -------------------------------------------------------------------------------- /neo4j/start.sh: -------------------------------------------------------------------------------- 1 | . ./path_neo4j.sh 2 | $NEO4J_HOME/bin/neo4j start 3 | 4 | -------------------------------------------------------------------------------- /neo4j/stop.sh: -------------------------------------------------------------------------------- 1 | . ./path_neo4j.sh 2 | $NEO4J_HOME/bin/neo4j stop 3 | 4 | -------------------------------------------------------------------------------- /neo4j/switch.sh: -------------------------------------------------------------------------------- 1 | #. ./path_neo4j.sh 2 | 3 | db=$1 4 | NEO4J_DB_DIR=$NEO4J_HOME/data/databases/$db.db 5 | 6 | $NEO4J_HOME/bin/neo4j stop 7 | 8 | rm -rf $NEO4J_HOME/data/databases/graph.db 9 | ln -s $NEO4J_HOME/data/databases/"$db".db $NEO4J_HOME/data/databases/graph.db 10 | 11 | $NEO4J_HOME/bin/neo4j start 12 | 13 | sleep 15 14 | -------------------------------------------------------------------------------- /neo4j/warm_up.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_warm_up(name_data): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/warm_up" + "_" + name_data, 'a') 21 | runner = Neo4jQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | start = timer() 27 | runner.warm_up(name_data) 28 | end = timer() 29 | exe_time = end - start 30 | total_time += exe_time 31 | line = "warm_up," + str(name_data) + "," + str(exe_time) + " seconds" 32 | print(line) 33 | report += line + "\n" 34 | report += "summary," + "warm_up," + str(name_data) + "," + str(total_time) + " seconds" 35 | ofile.write(report) 36 | print (report) 37 | 38 | 39 | if __name__ == "__main__": 40 | # kn.py file_name db_name num_iteration 41 | if len(sys.argv) < 2: 42 | print("Usage: python warm_up.py name_data") 43 | sys.exit() 44 | # python warm_up.py snb_1 933 3 45 | run_warm_up(os.path.basename(sys.argv[1]) if len(sys.argv) == 2 else "") 46 | 47 | -------------------------------------------------------------------------------- /neo4j/which.sh: -------------------------------------------------------------------------------- 1 | echo NEO4J_DB 2 | grep -E -o '.{0,10}neostore.counts.db.b' $NEO4J_DB_DIR/logs/debug.log 3 | -------------------------------------------------------------------------------- /paper/DoWeNeedGraphDB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/DoWeNeedGraphDB.pdf -------------------------------------------------------------------------------- /paper/Introducing_the_graph_500.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/Introducing_the_graph_500.pdf -------------------------------------------------------------------------------- /paper/LDBC-Graphalytics_tech-specs_v0.9.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/LDBC-Graphalytics_tech-specs_v0.9.0.pdf -------------------------------------------------------------------------------- /paper/TigerGraph evaluation V2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/TigerGraph evaluation V2.pdf -------------------------------------------------------------------------------- /paper/Tigergraph-benchmark-report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/Tigergraph-benchmark-report.pdf -------------------------------------------------------------------------------- /paper/graph_database_ubiquity.pdf.: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/graph_database_ubiquity.pdf. -------------------------------------------------------------------------------- /paper/gsql_ddl_loading_v2.1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/gsql_ddl_loading_v2.1.pdf -------------------------------------------------------------------------------- /paper/gsql_query_v2.1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/gsql_query_v2.1.pdf -------------------------------------------------------------------------------- /paper/ldbc-analytic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/ldbc-analytic.pdf -------------------------------------------------------------------------------- /paper/ldbc-snb-interactive-paper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/ldbc-snb-interactive-paper.pdf -------------------------------------------------------------------------------- /paper/ldbc-snb-specification.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/ldbc-snb-specification.pdf -------------------------------------------------------------------------------- /paper/ldbc_snb_bi_early_look.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/paper/ldbc_snb_bi_early_look.pdf -------------------------------------------------------------------------------- /tigergraph/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | NEO4J_BOLT= os.environ.get("NEO4J_BOLT", "bolt://127.0.0.1:7687") 4 | TIGERGRAPH_HTTP = os.environ.get("TIGERGRAPH_HTTP", "http://127.0.0.1:9000") 5 | -------------------------------------------------------------------------------- /tigergraph/grestart.sh: -------------------------------------------------------------------------------- 1 | gadmin restart -y; gadmin restart ts3 -y; gadmin restart gpe -y; 2 | -------------------------------------------------------------------------------- /tigergraph/gstop.sh: -------------------------------------------------------------------------------- 1 | gadmin stop all -y; gadmin stop admin -y; gadmin stop ts3 -y; 2 | 3 | pkill -u tigergraph 4 | -------------------------------------------------------------------------------- /tigergraph/i_short_1.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_1(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_1" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_1(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_1," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_1," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_1.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_1.py snb_1 933 3 48 | run_i_short_1(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_2.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_2(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_2" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_2(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_2," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_2," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_2.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_2.py snb_1 933 3 48 | run_i_short_2(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_3.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_3(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_3" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_3(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_3," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_3," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_3.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_3.py snb_1 933 3 48 | run_i_short_3(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_4.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_4(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_4" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_4(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_4," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_4," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_4.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_4.py snb_1 933 3 48 | run_i_short_4(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_5.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_5(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_5" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_5(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_5," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_5," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_5.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_5.py snb_1 933 3 48 | run_i_short_5(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_6.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_6(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_6" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_6(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_6," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_6," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_6.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_6.py snb_1 933 3 48 | run_i_short_6(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/i_short_7.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | import datetime 5 | from timeit import default_timer as timer 6 | 7 | from query_runner import * 8 | from config import * 9 | 10 | def run_i_short_7(name_data, param, num_tests): 11 | #create result folder 12 | if not os.path.exists(os.path.dirname("./result/")): 13 | try: 14 | os.makedirs(os.path.dirname("./result/")) 15 | except OSError as exc: # Guard against race condition 16 | if exc.errno != errno.EEXIST: 17 | raise 18 | 19 | 20 | ofile = open("result/i_short_7" + "_" + name_data, 'a') 21 | runner = TigerGraphQueryRunner(); 22 | 23 | total_time = 0.0 24 | total_knsize = 0 25 | report = "\n---------- " + str(datetime.datetime.now()) + " " + " ----------\n" 26 | 27 | 28 | for i in range(0, num_tests): 29 | start = timer() 30 | runner.i_short_7(param) 31 | end = timer() 32 | exe_time = end - start 33 | total_time += exe_time 34 | line = str(i) + "," + "i_short_7," + str(param) + "," + str(exe_time) + " seconds" 35 | print(line) 36 | report += line + "\n" 37 | report += "summary," + "i_short_7," + str(param) + "," + str(total_time/num_tests) + " seconds" 38 | ofile.write(report) 39 | print (report) 40 | 41 | 42 | if __name__ == "__main__": 43 | # kn.py file_name db_name num_iteration 44 | if len(sys.argv) < 3: 45 | print("Usage: python i_short_7.py name_data param num_tests") 46 | sys.exit() 47 | # python i_short_7.py snb_1 933 3 48 | run_i_short_7(os.path.basename(sys.argv[1]), sys.argv[2], int(sys.argv[3]) if len(sys.argv) == 4 else "") 49 | 50 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/README.txt: -------------------------------------------------------------------------------- 1 | path.sh 2 | #set path to raw data directory 3 | 4 | convert_data.sh 5 | #1. convert city/country/continent to City/Country/Continent 6 | convert company/university to Company/University 7 | #2. convert all data of datetime type to integers 8 | 9 | 10 | split_data.sh 11 | split data: 12 | #split vertexes: 13 | #place to city/country/continent 14 | #organisation to university/company 15 | 16 | #split edges: 17 | #place_isPartOf_place to city_isPartOf_country/country_isPartOf_continent 18 | #organisation_isLocatedIn_place to university_isLocatedIn_city/company_isLocatedIn_country 19 | #organisation_isLocatedIn_place to university_isLocatedIn_city/company_isLocatedIn_country 20 | 21 | 22 | setup_schema.gsql 23 | #setup schema 24 | 25 | 26 | setup_schema_split.gsql 27 | #setup schema with splited data 28 | 29 | 30 | load_data.sh 31 | #load converted data into TigerGraph 32 | 33 | 34 | load_data_split.sh 35 | #load converted and splited data into Tigergraph 36 | 37 | 38 | load_in_one_step.sh 39 | #execute convert_date.sh, setup_schema.gsql, load_data.sh one by one 40 | 41 | 42 | load_in_one_step_split.sh 43 | #execute convert_data.sh, split_data.sh, setup_schema_split.gsql, load_data_splited one by one 44 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/SplitEdges: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/tigergraph/load_scripts/SplitEdges -------------------------------------------------------------------------------- /tigergraph/load_scripts/SplitPlace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuang29/graph_database_benchmark/2fee337317fd029fb37cf5b434eb9967a127be9b/tigergraph/load_scripts/SplitPlace -------------------------------------------------------------------------------- /tigergraph/load_scripts/convert_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # replace labels with one starting with an uppercase letter 4 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-3 5 | #export POSTFIX=_0_0.csv 6 | sed -i "s/|city$/|City/" "${RAW_DATA_DIR}/place${POSTFIX}" 7 | sed -i "s/|country$/|Country/" "${RAW_DATA_DIR}/place${POSTFIX}" 8 | sed -i "s/|continent$/|Continent/" "${RAW_DATA_DIR}/place${POSTFIX}" 9 | sed -i "s/|company|/|Company|/" "${RAW_DATA_DIR}/organisation${POSTFIX}" 10 | sed -i "s/|university|/|University|/" "${RAW_DATA_DIR}/organisation${POSTFIX}" 11 | 12 | rename 's/comment/comments/g' ${RAW_DATA_DIR}/*.csv 13 | 14 | #sed -i "s/|city$/|City/" "${RAW_DATA_DIR}/city/city.csv" 15 | #sed -i "s/|country$/|Country/" "${RAW_DATA_DIR}/country/country.csv" 16 | #sed -i "s/|continent$/|Continent/" "${RAW_DATA_DIR}/continent/continent.csv" 17 | #sed -i "s/|company|/|Company|/" "${RAW_DATA_DIR}/organisation/organisation${POSTFIX}" 18 | #sed -i "s/|university|/|University|/" "${RAW_DATA_DIR}/organisation/organisation${POSTFIX}" 19 | 20 | # convert each date of format yyyy-mm-dd to a number of format yyyymmddd 21 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)|#|\1\2\3|#g" "${RAW_DATA_DIR}/person${POSTFIX}" 22 | 23 | # convert each datetime of format yyyy-mm-ddThh:mm:ss.mmm+0000 24 | # to a number of format yyyymmddhhmmssmmm 25 | #sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)T\([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)+0000#|\1\2\3\4\5\6\7#g" ${RAW_DATA_DIR}/*${POSTFIX} 26 | 27 | sed -i "s#|\([0-9][0-9][0-9][0-9]\)-\([0-9][0-9]\)-\([0-9][0-9]\)T\([0-9][0-9]\):\([0-9][0-9]\):\([0-9][0-9]\)\.\([0-9][0-9][0-9]\)+0000#|\1\2\3\4\5\6\7#g" ${RAW_DATA_DIR}/*.csv 28 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/load_data_split_time.sh: -------------------------------------------------------------------------------- 1 | # raw data path 2 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-1-test/ 3 | schema=setup_schema_split.gsql 4 | 5 | . ./path.sh 6 | 7 | gsql $schema 8 | 9 | t0=$(date +%s%N) 10 | bash load_data_split.sh 11 | tn=$(date +%s%N) 12 | t=$((($tn - $t0)/1000000)) 13 | echo $t $RAW_DATA_DIR 14 | echo $t $RAW_DATA_DIR >> ./loading.out 15 | du -sb /local-disk/tigergraph/gstore/ 16 | du -sb /local-disk/tigergraph/gstore/ >> ./loading.out 17 | echo "------------------------------completed load data---------------------------------------" 18 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/load_data_time.sh: -------------------------------------------------------------------------------- 1 | # raw data path 2 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-1-test/ 3 | schema=setup_schema.gsql 4 | 5 | . ./path.sh 6 | 7 | gsql $schema 8 | 9 | t0=$(date +%s%N) 10 | bash load_data.sh 11 | tn=$(date +%s%N) 12 | t=$((($tn - $t0)/1000000)) 13 | echo $t $RAW_DATA_DIR 14 | echo $t $RAW_DATA_DIR >> ./loading.out 15 | du -sb /home/tigergraph/tigergraph/gstore/ 16 | du -sb /home/tigergraph/tigergraph/gstore/ >> ./loading.out 17 | echo "------------------------------completed load data---------------------------------------" 18 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/load_in_one_step.sh: -------------------------------------------------------------------------------- 1 | # raw data path 2 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-1-test/ 3 | 4 | . ./path.sh 5 | echo "------------------------------completed set path----------------------------" 6 | 7 | bash convert_data.sh 8 | echo "------------------------------completed convert raw data----------------------------" 9 | 10 | gsql setup_schema.gsql 11 | echo "------------------------------completed setup schema---------------------------------------" 12 | 13 | t0=$(date +%s%N) 14 | bash load_data.sh 15 | tn=$(date +%s%N) 16 | t=$((($tn - $t0)/1000000)) 17 | echo $t $RAW_DATA_DIR 18 | echo $t $RAW_DATA_DIR >> ./loading.out 19 | du -sb /home/tigergraph/tigergraph/gstore/ 20 | du -sb /home/tigergraph/tigergraph/gstore/ >> ./loading.out 21 | echo "------------------------------completed load data---------------------------------------" 22 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/load_in_one_step_split.sh: -------------------------------------------------------------------------------- 1 | # raw data path 2 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-1-test/ 3 | 4 | . ./path.sh 5 | echo "------------------------------completed set path----------------------------" 6 | 7 | bash convert_data.sh 8 | echo "------------------------------completed convert raw data----------------------------" 9 | 10 | gsql setup_schema_split.gsql 11 | echo "------------------------------completed setup schema---------------------------------------" 12 | 13 | t0=$(date +%s%N) 14 | bash load_data_split.sh 15 | tn=$(date +%s%N) 16 | t=$((($tn - $t0)/1000000)) 17 | echo $t $RAW_DATA_DIR 18 | echo $t $RAW_DATA_DIR >> ./loading_split.out 19 | du -sb /home/tigergraph/tigergraph/gstore/ 20 | du -sb /home/tigergraph/tigergraph/gstore/ >> ./loading_split.out 21 | echo "------------------------------completed load data---------------------------------------" 22 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/path.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network_300 4 | export POSTFIX=_0_0.csv 5 | 6 | # numThreads specified in ldbc_snb_datagen/params.ini 7 | export TOTAL_FILE_NUMBER=1 8 | 9 | echo $RAW_DATA_DIR 10 | -------------------------------------------------------------------------------- /tigergraph/load_scripts/split_data.sh: -------------------------------------------------------------------------------- 1 | #export RAW_DATA_DIR=/home/zhiyi/raw/snb/tigergraph/social_network-1-test/ #change to your raw data file 2 | #export TOTAL_FILE_NUMBER=1 # numThreads specified in ldbc_snb_datagen/params.ini 3 | 4 | echo "split vertrex place into city, country, continent" 5 | g++ --std=c++11 SplitPlace.cpp -o SplitPlace 6 | ./SplitPlace ${RAW_DATA_DIR} ${TOTAL_FILE_NUMBER} 7 | echo "#####################################################" 8 | echo "split vertex organisation done" 9 | 10 | 11 | echo "split vertrex organisation to company, university" 12 | g++ --std=c++11 SplitOrganisation.cpp -o SplitOrganisation 13 | ./SplitOrganisation ${RAW_DATA_DIR} ${TOTAL_FILE_NUMBER} 14 | echo "#####################################################" 15 | echo "split vertex organisation done" 16 | 17 | 18 | i="0" 19 | while [ $i -lt ${TOTAL_FILE_NUMBER} ] 20 | do 21 | # rm "${RAW_DATA_DIR}place_${i}_0.csv" 22 | i=$[$i+1] 23 | done 24 | 25 | echo "#####################################################" 26 | echo "split edge organisation_isLocatedIn_place into: 27 | university_isLocatedIn_city, company_isLocatedIn_country" 28 | echo "split edge place_isPartOf_place into: 29 | city_isPartOf_country, country_isPartOf_continent" 30 | g++ --std=c++11 SplitEdges.cpp -o SplitEdges 31 | ./SplitEdges ${RAW_DATA_DIR} ${TOTAL_FILE_NUMBER} 32 | 33 | echo "#####################################################" 34 | echo "split organisation_isLocatedIn_place_#_0.csv, place_isLocatedIn_place done" 35 | 36 | i="0" 37 | while [ $i -lt ${TOTAL_FILE_NUMBER} ] 38 | do 39 | # rm "${RAW_DATA_DIR}organisation_isLocatedIn_place_${i}_0.csv" 40 | # rm "${RAW_DATA_DIR}place_isPartOf_place_${i}_0.csv" 41 | i=$[$i+1] 42 | done 43 | -------------------------------------------------------------------------------- /tigergraph/queries/bi_.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query bi_ 3 | 4 | create query bi_(STRING vid) for graph ldbc { 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | } 21 | install query bi_ 22 | -------------------------------------------------------------------------------- /tigergraph/queries/bi_1.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query bi_1 3 | 4 | create query bi_1(String date) for graph ldbc { 5 | 6 | 7 | 8 | 9 | } 10 | install query bi_1 11 | -------------------------------------------------------------------------------- /tigergraph/queries/bi_15.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query bi_15 3 | 4 | create query bi_15(String countryName) for graph ldbc { 5 | SumAccum @@totalCount; 6 | SetAccum @@personSet; 7 | SetAccum @@citySet; 8 | 9 | INT socialNormal; 10 | 11 | Person = {person.*}; 12 | Person1 = {person.*}; 13 | Person2 = {person.*}; 14 | City = {city.*}; 15 | Country = {country.*}; 16 | 17 | Country = SELECT s 18 | FROM country:s 19 | WHERE s.name == countryName; 20 | 21 | City = SELECT s 22 | FROM city:s-(city_isPartOf_country)->:t 23 | WHERE t == Country 24 | ACCUM @@citySet += s.id; 25 | 26 | Person1 = SELECT s 27 | FROM Person:s-(person_isLocatedIn_city)->:t 28 | WHERE t.id IN @@citySet; 29 | ACCUM @@personSet += s.id; 30 | 31 | Person1 = SELECT s 32 | FROM Person1:s-(person_knows_person)->:t 33 | WHERE t.id IN @@personSet 34 | ACCUM s.@count += 1, @@totalCount += 1; 35 | 36 | socialNormal = float_to_int(@@totalCount / Person1.size()); 37 | 38 | Person1 = SELECT s 39 | WHERE s.@count == socialNormal; 40 | ORDER by s.id 41 | LIMIT 100; 42 | 43 | PRINT Forum.id, Forum.@count1, Forum.@count2; 44 | } 45 | install query bi_15 46 | -------------------------------------------------------------------------------- /tigergraph/queries/i_complex_.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_complex_ 3 | 4 | create query i_complex_(STRING vid) for graph ldbc { 5 | 6 | } 7 | install query i_complex_ 8 | -------------------------------------------------------------------------------- /tigergraph/queries/i_complex_13.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_complex_13 3 | 4 | CREATE QUERY i_complex_13 (VERTEX S, VERTEX T, INT maxDepth) FOR GRAPH ldbc{ 5 | 6 | MinAccum @@dis; 7 | OrAccum @@found = false; 8 | OrAccum @notSeen = true; 9 | ListAccum @pathResult; 10 | 11 | Start (ANY) = {S}; 12 | 13 | //intialization 14 | Start = SELECT v 15 | FROM Start:v 16 | ACCUM v.@notSeen = false, v.@pathResult = to_string(v.id); 17 | 18 | //get shortest path from S to T within maxDepth 19 | WHILE NOT @@found LIMIT maxDepth DO 20 | Start = SELECT v 21 | FROM Start - (person_knows_person:e) -> :v 22 | WHERE v.@notSeen 23 | ACCUM v.@notSeen = false, 24 | FOREACH path IN Start.@pathResult DO 25 | v.@pathResult += (path + "-" + to_string(v.id)), 26 | @@dis += 1 27 | END, 28 | CASE WHEN v == T 29 | THEN @@found += true 30 | END; 31 | END; 32 | 33 | IF S.id == T.id THEN 34 | PRINT "0"; 35 | ELSE IF @@found THEN 36 | Result = {T}; 37 | PRINT Result [Result.@pathResult]; 38 | PRINT @@dis; 39 | ELSE 40 | PRINT "-1"; 41 | END; 42 | } 43 | INSTALL QUERY i_complex_13 44 | -------------------------------------------------------------------------------- /tigergraph/queries/i_complex_2.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_complex_ 3 | 4 | create query i_complex_(INT vid, UINT date) for graph ldbc { 5 | 6 | 7 | Person = {person.*}; 8 | Post = {post.*}; 9 | Comment = {comment.*}; 10 | 11 | Person = SELECT t 12 | FROM Person:s-(person_knows_person)->:t 13 | WHERE s.id == vid; 14 | 15 | Person = SELECT s 16 | FROM Person:s-(post_hasCreator_person_reverse)->:t 17 | WHERE t.creationDate <= date 18 | ACCUM 19 | 20 | 21 | } 22 | install query i_complex_ 23 | -------------------------------------------------------------------------------- /tigergraph/queries/i_short_.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_short_NO 3 | 4 | create query i_short_NO(STRING vid) for graph ldbc { 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | } 14 | install query i_short_NO 15 | -------------------------------------------------------------------------------- /tigergraph/queries/i_short_1.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_short_1 3 | 4 | create query i_short_1(INT vid) for graph ldbc { 5 | 6 | SumAccum @cityid; 7 | Person = {person.*}; 8 | city = {place.*}; 9 | 10 | Person = SELECT s 11 | FROM Person:s-(person_isLocatedIn_place)->:t 12 | WHERE s.id == vid 13 | ACCUM s.@cityid = t.id; 14 | PRINT Person.firstName, Person.lastName, Person.birthday, Person.locationIP, Person.browserUsed, Person.@cityid, Person.gender, Person.creationDate; 15 | 16 | } 17 | install query i_short_1 18 | -------------------------------------------------------------------------------- /tigergraph/queries/i_short_3.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_short_3 3 | 4 | create query i_short_3(INT vid) for graph ldbc { 5 | SumAccum @creationDate; 6 | Person = {person.*}; 7 | 8 | Person = SELECT s 9 | FROM Person:s-(person_knows_person)->:t 10 | WHERE t.id == vid 11 | ACCUM s.@creationDate = person_knows_person.creationDate 12 | ORDER BY s.@creationDate DESC, s.id; 13 | Print Person.id, Person.firstName, Person.lastName, Person.@creationDate; 14 | } 15 | install query i_short_3 16 | -------------------------------------------------------------------------------- /tigergraph/queries/i_short_4.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_short_4 3 | 4 | create query i_short_4(INT vid) for graph ldbc { 5 | SumAccum @@hasContent = 0; 6 | SumAccum @@isPost = 0; 7 | SumAccum @@isComment = 0; 8 | Post = {post.*}; 9 | Comment = {comments.*}; 10 | V = {post.*, comments.*}; 11 | 12 | V = SELECT s 13 | FROM V:s 14 | WHERE s.id == vid 15 | ACCUM 16 | CASE WHEN s.content != "" THEN 17 | @@hasContent += 1 END; 18 | 19 | IF V.size() == 1 AND @@hasContent == 1 THEN 20 | PRINT V.id, V.creationDate, V.content; 21 | ELSE IF V.size() == 1 AND @@hasContent == 0 THEN 22 | PRINT V.id, V.creationDate, V.imageFile; 23 | ELSE PRINT "None"; 24 | END; 25 | 26 | } 27 | install query i_short_4 28 | -------------------------------------------------------------------------------- /tigergraph/queries/i_short_5.gsql: -------------------------------------------------------------------------------- 1 | use graph ldbc 2 | drop query i_short_5 3 | 4 | create query i_short_5(INT vid) for graph ldbc { 5 | SumAccum @@isPost = 0; 6 | SumAccum @@isComment = 0; 7 | Post = {post.*}; 8 | Comment = {comments.*}; 9 | Person = {person.*}; 10 | 11 | //if message is post, return post creator 12 | postCreator = SELECT s 13 | FROM Person:s-(post_hasCreator_person_reverse)->:t 14 | WHERE t.id == vid 15 | ACCUM @@isPost += 1; 16 | 17 | //if message is comment, return comment creator 18 | commentCreator = SELECT s 19 | FROM Person:s-(comments_hasCreator_person_reverse)->:t 20 | WHERE t.id == vid 21 | ACCUM @@isComment += 1; 22 | 23 | IF @@isPost == 1 THEN 24 | PRINT postCreator.id, postCreator.firstName, postCreator.lastName; 25 | ELSE IF @@isComment == 1 THEN 26 | PRINT commentCreator.id, commentCreator.firstName, commentCreator.lastName; 27 | ELSE 28 | PRINT "None"; 29 | END; 30 | } 31 | install query i_short_5 32 | -------------------------------------------------------------------------------- /tigergraph/queries/install.sh: -------------------------------------------------------------------------------- 1 | gsql i_short_1.gsql 2 | gsql i_short_2.gsql 3 | gsql i_short_3.gsql 4 | gsql i_short_4.gsql 5 | gsql i_short_5.gsql 6 | gsql i_short_6.gsql 7 | gsql i_short_7.gsql 8 | -------------------------------------------------------------------------------- /tigergraph/run_i_short.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | python i_short_1.py snb_1 30786325583618 5 4 | python i_short_2.py snb_1 30786325583618 5 5 | python i_short_3.py snb_1 30786325583618 5 6 | python i_short_4.py snb_1 1236950581248 5 7 | python i_short_5.py snb_1 1236950581248 5 8 | python i_short_6.py snb_1 1236950581248 5 9 | python i_short_7.py snb_1 1236950581248 5 10 | --------------------------------------------------------------------------------